[提示] 关于死循环检测
fantasticsoul opened this issue · 1 comments
fantasticsoul commented
3.5.5 开始草稿依赖收集功能默认支持,无需开启,并提供的强大的死循环检测功能,通过 alert 和 控制台输出方式帮用户地位死循环位置
关闭alert
不配置alertDeadCycleErr
时,开发环境弹死循环提示,生产环境不弹,支持人工设置
const x = atomx({ a: 1, b: 2 }, { moduleName: 'yy', alertDeadCycleErr: false });
死循环案例
helux
能检测以下几种常见的触发死循环情况,并主动阻止无限调用情况产生
watch 回调里修改自身依赖
const [state, , ctxp] = share(dictFactory, { moduleName: 'Case3' });
watch(() => {
ctxp.reactive.f += 2;
}, () => [ctxp.reactive.f]);
watch(() => {
setState(draft => { draft.f += 2 });
}, () => [ctxp.reactive.f]);
mutate fn、task回调里修改自身依赖
fn里 读取自己修改自己,触发死循环
const witness = mutate(finalPriceState)({
fn: (draft) => {
draft.time += 1;
},
desc: 'dangerousMutate',
});
task 里修改依赖列表里的值,触发死循环
const witness = mutate(finalPriceState)({
deps: () => [priceState.a, finalPriceState.retA, finalPriceState.retB] as const,
task: async ({ input: [a], setState, draft }) => {
draft.retA += a; // 触发死循环
setState(draft => { draft.retB += a }); // 触发死循环
},
desc: 'dangerousMutate',
immediate: true,
});
多个函数间相互依赖形成死循环
多个 mutate 函数间的依赖闭环了形成相互依赖的局面,仅为导致死循环
// 发现a变化执行 changeB ---> 发现b变化执行 changeC ---> 发现c变化执行 changeA ---> infinity loop
const [state] = atom(
{ a: 1, b: 0, c: 0 },
{
mutate: {
changeB: (draft) => {
draft.b = draft.a + 10;
},
changeC: (draft) => {
draft.c = draft.b + 20;
},
changeA: (draft) => {
draft.a = draft.c + 30;
},
},
},
);
zhangfisher commented
死循环存在漏洞
重现在https://github.com/zhangfisher/speed-form
的docs文档示例中,当开启时会一直提示存在死循环,但实际并没有