[FIX] concurrency: do not render delayed fibers when cancelled

Previously, if a fiber was delayed because one of its ancestors was
rendering, and that fiber was not a root fiber, it would be rendered
after all its ancestors had finished rendering even if one of those
ancestor renderings cancelled it.

This commit fixes that by simply checking that a delayed fiber is still
its component node's current fiber before rendering it.
This commit is contained in:
Samuel Degueldre
2022-04-15 11:41:41 +02:00
committed by Géry Debongnie
parent 41344ef4ec
commit 41f1262eb7
5 changed files with 152 additions and 10 deletions
+5
View File
@@ -42,6 +42,10 @@ export function makeRootFiber(node: ComponentNode): Fiber {
return fiber;
}
function throwOnRender() {
throw new Error("Attempted to render cancelled fiber");
}
/**
* @returns number of not-yet rendered fibers cancelled
*/
@@ -49,6 +53,7 @@ function cancelFibers(fibers: Fiber[]): number {
let result = 0;
for (let fiber of fibers) {
let node = fiber.node;
fiber.render = throwOnRender;
if (node.status === STATUS.NEW) {
node.destroy();
}
+1 -1
View File
@@ -32,7 +32,7 @@ export class Scheduler {
let renders = this.delayedRenders;
this.delayedRenders = [];
for (let f of renders) {
if (f.root && f.node.status !== STATUS.DESTROYED) {
if (f.root && f.node.status !== STATUS.DESTROYED && f.node.fiber === f) {
f.render();
}
}