diff --git a/src/app/app.ts b/src/app/app.ts index 61de942d..ce7fd846 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -101,6 +101,7 @@ export class App< destroy() { if (this.root) { + this.scheduler.flush(); this.root.destroy(); } } diff --git a/src/component/component_node.ts b/src/component/component_node.ts index fd3749fd..17a0af39 100644 --- a/src/component/component_node.ts +++ b/src/component/component_node.ts @@ -245,7 +245,8 @@ export class ComponentNode

implements VNode = new Set(); - isRunning: boolean = false; requestAnimationFrame: Window["requestAnimationFrame"]; + frame: number = 0; constructor() { this.requestAnimationFrame = Scheduler.requestAnimationFrame; } - start() { - this.isRunning = true; - this.scheduleTasks(); - } - - stop() { - this.isRunning = false; - } - addFiber(fiber: Fiber) { this.tasks.add(fiber.root!); - if (!this.isRunning) { - this.start(); - } } /** @@ -39,39 +27,34 @@ export class Scheduler { * Other tasks are left unchanged. */ flush() { - this.tasks.forEach((fiber) => { - if (fiber.root !== fiber) { - this.tasks.delete(fiber); - return; - } - const hasError = fibersInError.has(fiber); - if (hasError && fiber.counter !== 0) { - this.tasks.delete(fiber); - return; - } - if (fiber.node.status === STATUS.DESTROYED) { - this.tasks.delete(fiber); - return; - } - - if (fiber.counter === 0) { - if (!hasError) { - fiber.complete(); - } - this.tasks.delete(fiber); - } - }); - if (this.tasks.size === 0) { - this.stop(); + if (this.frame === 0) { + this.frame = this.requestAnimationFrame(() => { + this.frame = 0; + this.tasks.forEach((fiber) => this.processFiber(fiber)); + }); } } - scheduleTasks() { - this.requestAnimationFrame(() => { - this.flush(); - if (this.isRunning) { - this.scheduleTasks(); + processFiber(fiber: RootFiber) { + if (fiber.root !== fiber) { + this.tasks.delete(fiber); + return; + } + const hasError = fibersInError.has(fiber); + if (hasError && fiber.counter !== 0) { + this.tasks.delete(fiber); + return; + } + if (fiber.node.status === STATUS.DESTROYED) { + this.tasks.delete(fiber); + return; + } + + if (fiber.counter === 0) { + if (!hasError) { + fiber.complete(); } - }); + this.tasks.delete(fiber); + } } }