From 2ff38d4cf3f19ab53ae1f734e0e8545fb7035b8a Mon Sep 17 00:00:00 2001 From: David Kondrad Date: Sat, 25 Jan 2020 12:21:55 -0500 Subject: [PATCH] Internals: Scheduler: Fix infinite loop in flush (#4316) --- src/runtime/internal/scheduler.ts | 7 ++++--- .../lifecycle-onmount-infinite-loop/Child.svelte | 1 + .../lifecycle-onmount-infinite-loop/_config.js | 6 ++++++ .../lifecycle-onmount-infinite-loop/main.svelte | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 04c1264ab1d2..1ce255b21772 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -31,8 +31,8 @@ export function add_flush_callback(fn) { flush_callbacks.push(fn); } +const seen_callbacks = new Set(); export function flush() { - const seen_callbacks = new Set(); do { // first, call beforeUpdate functions @@ -52,10 +52,10 @@ export function flush() { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { - callback(); - // ...so guard against infinite loops seen_callbacks.add(callback); + + callback(); } } @@ -67,6 +67,7 @@ export function flush() { } update_scheduled = false; + seen_callbacks.clear(); } function update($$) { diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte new file mode 100644 index 000000000000..ef16875b6448 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte @@ -0,0 +1 @@ +Child diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js new file mode 100644 index 000000000000..a76a2686ac27 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js @@ -0,0 +1,6 @@ +export default { + test({ assert, component }) { + const { count } = component; + assert.deepEqual(count, 1); + } +}; diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte new file mode 100644 index 000000000000..1fa4263e39ea --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte @@ -0,0 +1,16 @@ + + +