清理函数挂在哪一层,会改变等待顺序
同样要释放资源,兄弟项可以重叠,组合项会依次等待。切换登记方式和轨迹阶段,观察谁还在等待。
01 / 持有方式
图中连线表示清理函数的持有关系。yield 不会重写 Scope 的 Fiber.parent;原 disposer 是否移出顶层名单,取决于同 owner 中的函数身份。
兄弟 effect
逆序开始,异步清理仍会重叠
A 先登记、B 后登记。Fiber 反转顶层名单后,用 Promise.all 等待各项;A 可以在 B 仍待完成时结束。
02 / 选择轨迹阶段
B 已开始异步清理,A 尚未进入。
B:startB 尚未完成,A 的清理也已开始。
A:start实验先放行 A;B 仍然等待自己的 Promise。
A:end再放行 B,所有顶层清理结束,Owner 的卸载才完成。
B:end清理函数的持有关系 / 手机显示对应持有路径
查看本组登记代码返回持有关系图
登记形状节选,省略具体清理函数与受控 Promise。完整可运行断言见下载包。
inner.effect(() => releaseA) inner.effect(() => releaseB)
持有清理函数 · 描边加粗:本阶段关注项 · 阶段状态为轨迹示意
- effect AOwner Fiber → effect A 未开始 等待中 已结束 已结束
- effect BOwner Fiber → effect B 等待中 等待中 等待中 已结束
B:startB 开始A:startA 开始A:endA 结束B:endB 结束
确切 disposer
Scope 纳入组合,tail 会等待它
原 rawDispose 从当前 Fiber 顶层移入组合。组合按逆序清理 B、Scope、tail;Scope 的异步清理结束前,tail 不会运行。
02 / 选择轨迹阶段
B 为本组的同步清理,已经完成;接着才进入 Scope。
BScope 正在等待。tail 由同一组合持有,因此尚未调用。
scope:start受控 Promise 放行,Scope 清理已结束;下一项是 tail。
scope:end最后执行 tail,组合与 Owner 的清理结束。
tail清理函数的持有关系 / 手机显示对应持有路径
查看本组登记代码返回持有关系图
登记形状节选,省略具体清理函数与受控 Promise。完整可运行断言见下载包。
inner.effect(function* () {
yield releaseTail
const scope = createScope(inner, key)
yield scope.rawDispose
yield releaseB
})持有清理函数 · 描边加粗:本阶段关注项 · 阶段状态为轨迹示意
- releaseTailOwner Fiber → 组合 → releaseTail 未开始 未开始 未开始 已结束
- Scope rawDisposeOwner Fiber → 组合 → Scope rawDispose 未开始 等待中 已结束 已结束
- releaseBOwner Fiber → 组合 → releaseB 已结束 已结束 已结束 已结束
BB 结束scope:startScope 开始scope:endScope 结束tailtail 结束
新包装函数
调用目标相同,Scope 仍是顶层兄弟
组合收集的是新包装函数。原 rawDispose 留在 Fiber 顶层,可能在 B 尚未完成时开始;tail 也可能先于 Scope 完成。
02 / 选择轨迹阶段
组合先等待 B,Scope 的顶层清理任务也已被安排。
B:start原 rawDispose 仍由 Fiber 持有,Scope 此时与 B 同时待完成。
scope:start放行 B。Scope 仍然等待,组合将进入自己的新包装函数。
B:end包装函数再调用已经启动的 rawDispose,得到 undefined;本组 tail 因而先运行。
tail再放行 Scope。Owner 顶层仍等待它,整个卸载此时才完成。
scope:end清理函数的持有关系 / 手机显示对应持有路径
查看本组登记代码返回持有关系图
登记形状节选,省略具体清理函数与受控 Promise。完整可运行断言见下载包。
inner.effect(function* () {
yield releaseTail
const scope = createScope(inner, key)
yield () => scope.rawDispose()
yield releaseB
})持有清理函数 · 描边加粗:本阶段关注项 · 阶段状态为轨迹示意
- Scope rawDisposeOwner Fiber → Scope rawDispose 未开始 等待中 等待中 等待中 已结束
- releaseTailOwner Fiber → 组合 → releaseTail 未开始 未开始 未开始 已结束 已结束
- 新包装函数Owner Fiber → 组合 → 新包装函数 未调用 未调用 未调用 已调用 已调用
- releaseBOwner Fiber → 组合 → releaseB 等待中 等待中 已结束 已结束 已结束
B:startB 开始scope:startScope 开始B:endB 结束tailtail 结束scope:endScope 结束