handle nightmarish infinite loop situation

pull/1864/head
Rich Harris 7 years ago
parent 72f3fde2b8
commit e03f8d6590

@ -757,7 +757,7 @@ export default class ElementWrapper extends Wrapper {
block.builders.intro.addConditional(`@intro.enabled`, deindent` block.builders.intro.addConditional(`@intro.enabled`, deindent`
if (${name}) ${name}.invalidate(); if (${name}) ${name}.invalidate();
@after_update(() => { @after_render(() => {
if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
${name}.run(1); ${name}.run(1);
}); });
@ -792,7 +792,7 @@ export default class ElementWrapper extends Wrapper {
} }
block.builders.intro.addConditional(`@intro.enabled`, deindent` block.builders.intro.addConditional(`@intro.enabled`, deindent`
@after_update(() => { @after_render(() => {
${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true); ${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
${introName}.run(1); ${introName}.run(1);
}); });

@ -1,4 +1,4 @@
import { schedule_update, flush, intro } from './scheduler.js'; import { after_render, flush, intro, schedule_update } from './scheduler.js';
import { set_current_component } from './lifecycle.js' import { set_current_component } from './lifecycle.js'
import { is_function, run, run_all, noop } from './utils.js'; import { is_function, run, run_all, noop } from './utils.js';
import { blankObject } from './utils.js'; import { blankObject } from './utils.js';
@ -33,11 +33,13 @@ export class $$Component {
this.$$.inject_props(options.props); this.$$.inject_props(options.props);
} }
run_all(this.$$beforeRender);
this.$$fragment = this.$$create_fragment(this, this.$$.get_state()); this.$$fragment = this.$$create_fragment(this, this.$$.get_state());
if (options.target) { if (options.target) {
intro.enabled = !!options.intro; intro.enabled = !!options.intro;
this.$$mount(options.target); this.$$mount(options.target);
flush(); flush();
intro.enabled = true; intro.enabled = true;
} }
@ -90,7 +92,6 @@ export class $$Component {
} }
$$mount(target, anchor) { $$mount(target, anchor) {
run_all(this.$$beforeRender);
this.$$fragment.c(); this.$$fragment.c();
this.$$fragment[this.$$fragment.i ? 'i' : 'm'](target, anchor); this.$$fragment[this.$$fragment.i ? 'i' : 'm'](target, anchor);
this.$$.inject_refs(this.$$refs); this.$$.inject_refs(this.$$refs);
@ -99,15 +100,16 @@ export class $$Component {
this.$$onDestroy.push(...onDestroy); this.$$onDestroy.push(...onDestroy);
this.$$onMount = []; this.$$onMount = [];
run_all(this.$$afterRender); this.$$afterRender.forEach(after_render);
} }
$$update() { $$update() {
run_all(this.$$beforeRender); run_all(this.$$beforeRender);
this.$$fragment.p(this.$$dirty, this.$$.get_state()); this.$$fragment.p(this.$$dirty, this.$$.get_state());
this.$$.inject_refs(this.$$refs); this.$$.inject_refs(this.$$refs);
run_all(this.$$afterRender);
this.$$dirty = null; this.$$dirty = null;
this.$$afterRender.forEach(after_render);
} }
} }

@ -1,7 +1,7 @@
let update_scheduled = false; let update_scheduled = false;
const dirty_components = []; let dirty_components = [];
const after_update_callbacks = []; const after_render_callbacks = [];
export const intro = { enabled: false }; export const intro = { enabled: false };
@ -13,18 +13,33 @@ export function schedule_update(component) {
} }
} }
export function after_update(fn) { export function after_render(fn) {
after_update_callbacks.push(fn); after_render_callbacks.push(fn);
} }
export function flush() { export function flush() {
while (dirty_components.length) { const seen_callbacks = new Set();
dirty_components.pop().$$update();
} do {
// first, call beforeRender functions
while (after_update_callbacks.length) { // and update components
after_update_callbacks.shift()(); while (dirty_components.length) {
} dirty_components.shift().$$update();
}
// then, once components are updated, call
// afterRender functions. This may cause
// subsequent updates...
while (after_render_callbacks.length) {
const callback = after_render_callbacks.pop();
if (!seen_callbacks.has(callback)) {
callback();
// ...so guard against infinite loops
seen_callbacks.add(callback);
}
}
} while (dirty_components.length);
update_scheduled = false; update_scheduled = false;
} }

Loading…
Cancel
Save