第一步
按照先有的逻辑,如果像下面这种方式使用的话,会导致死循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div>
<script type="module"> import { reactive, effect } from './reactivity.js';
let obj = { name: 'xiaoming', age: 18, flag: true }; const state = reactive(obj);
effect(() => { app.innerHTML = state.name; state.name = Math.random(); }) </script> </body> </html>
|
name 的值改变了之后,会重新执行 effect 函数,这样就会导致死循环了
第二步
新增是否正在执行的标识 _running,进而来解决这种问题
effect.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| ... class ReactiveEffect { _trackId = 0; deps = []; _depsLength = 0; _running = 0;
run() { if (!this.active) { return this.fn(); }
let lastEffect = activeEffect; try { activeEffect = this;
preCleanEffect(this); this._running++;
return this.fn(); } finally { this._running--;
postCleanEffect(this);
activeEffect = lastEffect; } } }
export function triggerEffects(dep) { for (const effect of dep.keys()) { if (!effect._running) { if (effect.scheduler) { effect.scheduler(); } } } }
|