[feat] opt-out loopGuard for async loops (#6963)

pull/7015/head
Tan Li Hau 3 years ago committed by GitHub
parent f2d4a10741
commit 6ecc3e4d6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -24,7 +24,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
import fuzzymatch from '../utils/fuzzymatch';
import get_object from './utils/get_object';
import Slot from './nodes/Slot';
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration } from 'estree';
import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression } from 'estree';
import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, b } from 'code-red';
@ -766,12 +766,13 @@ export default class Component {
};
let scope_updated = false;
let generator_count = 0;
const current_function_stack = [];
let current_function: FunctionDeclaration | FunctionExpression = null;
walk(content, {
enter(node: Node, parent: Node, prop, index) {
if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) {
generator_count++;
if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) {
current_function_stack.push(current_function = node);
}
if (map.has(node)) {
@ -800,12 +801,13 @@ export default class Component {
},
leave(node: Node) {
if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) {
generator_count--;
if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) {
current_function_stack.pop();
current_function = current_function_stack[current_function_stack.length - 1];
}
// do it on leave, to prevent infinite loop
if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && generator_count <= 0) {
if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && (!current_function || (!current_function.generator && !current_function.async))) {
const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout);
if (to_replace_for_loop_protect) {
this.replace(to_replace_for_loop_protect);

@ -0,0 +1,9 @@
export default {
compileOptions: {
dev: true,
loopGuardTimeout: 1
},
async test({ component }) {
await component.run_async_function();
}
};

@ -0,0 +1,12 @@
<script>
export async function run_async_function() {
await loop();
}
async function loop() {
let i = 0;
while (i ++ < 5) {
await new Promise(resolve => setTimeout(resolve, 20));
}
}
</script>

@ -2,5 +2,8 @@ export default {
compileOptions: {
dev: true,
loopGuardTimeout: 1
},
async test({ component }) {
await component.run_generator();
}
};

@ -1,10 +1,12 @@
<script>
const it = gen();
it.next();
export async function run_generator() {
const it = gen();
it.next();
await new Promise(resolve => setTimeout(resolve, 20));
setTimeout(() => {
it.next();
}, 20)
}
function* gen() {
while (true) {

Loading…
Cancel
Save