From a7bbd785b51e0ef8e6940b47228ac0e690e5925b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E5=8D=8E?= Date: Wed, 16 Mar 2022 11:40:02 +0800 Subject: [PATCH 1/2] fix: nested effect --- src/reactivity/__tests__/effect.spec.ts | 29 +++++++++++++++++++++++++ src/reactivity/src/effect.ts | 8 ++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/reactivity/__tests__/effect.spec.ts b/src/reactivity/__tests__/effect.spec.ts index 6010da9e..2c31c19f 100644 --- a/src/reactivity/__tests__/effect.spec.ts +++ b/src/reactivity/__tests__/effect.spec.ts @@ -116,4 +116,33 @@ describe("effect", () => { stop(runner); expect(onStop).toHaveBeenCalled(); }); + + it.skip('nested effect', () => { + const obj = reactive({ foo: 1, bar: 1 }) + let temp1, temp2 + const outerCall = jest.fn() + const innerCall = jest.fn() + effect(() => { + outerCall() + effect(() => { + innerCall() + temp2 = obj.bar + }) + temp1 = obj.foo + }) + // 两个都会执行 + expect(outerCall).toBeCalledTimes(1) + expect(innerCall).toBeCalledTimes(1) + + obj.bar = 2 + // 只执行内层的 + expect(outerCall).toBeCalledTimes(1) + expect(innerCall).toBeCalledTimes(2) + + obj.foo = 2 + // 内外层都执行 + expect(outerCall).toBeCalledTimes(2) + expect(innerCall).toBeCalledTimes(3) + + }) }); diff --git a/src/reactivity/src/effect.ts b/src/reactivity/src/effect.ts index e5f35f3c..4503ff5b 100644 --- a/src/reactivity/src/effect.ts +++ b/src/reactivity/src/effect.ts @@ -4,6 +4,7 @@ import { extend } from "../../shared/index"; let activeEffect = void 0; let shouldTrack = false; const targetMap = new WeakMap(); +const effectStack: any[] = [] // 用于依赖收集 export class ReactiveEffect { @@ -34,11 +35,16 @@ export class ReactiveEffect { // 执行的时候给全局的 activeEffect 赋值 // 利用全局属性来获取当前的 effect activeEffect = this as any; + effectStack.push(this) // 执行用户传入的 fn console.log("执行用户传入的 fn"); const result = this.fn(); + effectStack.pop() + activeEffect = effectStack[effectStack.length - 1] // 重置 - shouldTrack = false; + if (effectStack.length === 0) { + shouldTrack = false + } activeEffect = undefined; return result; From b0d0d817d7287154df9d4b69acab8520feba39d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E5=8D=8E?= Date: Wed, 16 Mar 2022 13:38:35 +0800 Subject: [PATCH 2/2] fix: nested effect --- src/reactivity/__tests__/effect.spec.ts | 2 +- src/reactivity/src/effect.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/reactivity/__tests__/effect.spec.ts b/src/reactivity/__tests__/effect.spec.ts index 2c31c19f..49c34d96 100644 --- a/src/reactivity/__tests__/effect.spec.ts +++ b/src/reactivity/__tests__/effect.spec.ts @@ -117,7 +117,7 @@ describe("effect", () => { expect(onStop).toHaveBeenCalled(); }); - it.skip('nested effect', () => { + it('nested effect', () => { const obj = reactive({ foo: 1, bar: 1 }) let temp1, temp2 const outerCall = jest.fn() diff --git a/src/reactivity/src/effect.ts b/src/reactivity/src/effect.ts index 4503ff5b..019e445a 100644 --- a/src/reactivity/src/effect.ts +++ b/src/reactivity/src/effect.ts @@ -45,7 +45,6 @@ export class ReactiveEffect { if (effectStack.length === 0) { shouldTrack = false } - activeEffect = undefined; return result; }