Skip to content

Commit b0043ed

Browse files
committed
refactor: use class EffectScope implementation
1 parent e484b25 commit b0043ed

File tree

8 files changed

+98
-247
lines changed

8 files changed

+98
-247
lines changed
Lines changed: 42 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
1-
import {
2-
reactive,
3-
effect,
4-
effectScope,
5-
stop,
6-
isEffectScope,
7-
extendScope,
8-
computed,
9-
ref,
10-
onScopeStopped
11-
} from '../src'
1+
import { reactive, effect, EffectScope, onDispose } from '../src'
122

133
describe('reactivity/effect/scope', () => {
144
it('should run the passed function once (wrapped by a effect)', () => {
155
const fnSpy = jest.fn(() => {})
16-
effectScope(fnSpy)
6+
new EffectScope(fnSpy)
177
expect(fnSpy).toHaveBeenCalledTimes(1)
188
})
199

2010
it('should accept zero argument', () => {
21-
const scope = effectScope()
22-
expect(scope._scope.effects.length).toBe(0)
11+
const scope = new EffectScope()
12+
expect(scope.effects.length).toBe(0)
2313
})
2414

2515
it('should collect the effects', () => {
26-
const scope = effectScope(() => {
16+
const scope = new EffectScope(() => {
2717
let dummy
2818
const counter = reactive({ num: 0 })
2919
effect(() => (dummy = counter.num))
@@ -33,26 +23,26 @@ describe('reactivity/effect/scope', () => {
3323
expect(dummy).toBe(7)
3424
})
3525

36-
expect(scope._scope.effects.length).toBe(1)
26+
expect(scope.effects.length).toBe(1)
3727
})
3828

3929
it('stop', () => {
4030
let dummy, doubled
4131
const counter = reactive({ num: 0 })
4232

43-
const scope = effectScope(() => {
33+
const scope = new EffectScope(() => {
4434
effect(() => (dummy = counter.num))
4535
effect(() => (doubled = counter.num * 2))
4636
})
4737

48-
expect(scope._scope.effects.length).toBe(2)
38+
expect(scope.effects.length).toBe(2)
4939

5040
expect(dummy).toBe(0)
5141
counter.num = 7
5242
expect(dummy).toBe(7)
5343
expect(doubled).toBe(14)
5444

55-
stop(scope)
45+
scope.stop()
5646

5747
counter.num = 6
5848
expect(dummy).toBe(7)
@@ -63,24 +53,24 @@ describe('reactivity/effect/scope', () => {
6353
let dummy, doubled
6454
const counter = reactive({ num: 0 })
6555

66-
const scope = effectScope(() => {
56+
const scope = new EffectScope(() => {
6757
effect(() => (dummy = counter.num))
6858
// nested scope
69-
effectScope(() => {
59+
new EffectScope(() => {
7060
effect(() => (doubled = counter.num * 2))
7161
})
7262
})
7363

74-
expect(scope._scope.effects.length).toBe(2)
75-
expect(isEffectScope(scope._scope.effects[1])).toBe(true)
64+
expect(scope.effects.length).toBe(2)
65+
expect(scope.effects[1]).toBeInstanceOf(EffectScope)
7666

7767
expect(dummy).toBe(0)
7868
counter.num = 7
7969
expect(dummy).toBe(7)
8070
expect(doubled).toBe(14)
8171

8272
// stop the nested scope as well
83-
stop(scope)
73+
scope.stop()
8474

8575
counter.num = 6
8676
expect(dummy).toBe(7)
@@ -91,25 +81,22 @@ describe('reactivity/effect/scope', () => {
9181
let dummy, doubled
9282
const counter = reactive({ num: 0 })
9383

94-
const scope = effectScope(() => {
84+
const scope = new EffectScope(() => {
9585
effect(() => (dummy = counter.num))
9686
// nested scope
97-
effectScope(
98-
() => {
99-
effect(() => (doubled = counter.num * 2))
100-
},
101-
{ detached: true }
102-
)
87+
new EffectScope(() => {
88+
effect(() => (doubled = counter.num * 2))
89+
}, true)
10390
})
10491

105-
expect(scope._scope.effects.length).toBe(1)
92+
expect(scope.effects.length).toBe(1)
10693

10794
expect(dummy).toBe(0)
10895
counter.num = 7
10996
expect(dummy).toBe(7)
11097
expect(doubled).toBe(14)
11198

112-
stop(scope)
99+
scope.stop()
113100

114101
counter.num = 6
115102
expect(dummy).toBe(7)
@@ -122,44 +109,46 @@ describe('reactivity/effect/scope', () => {
122109
let dummy, doubled
123110
const counter = reactive({ num: 0 })
124111

125-
const scope = effectScope(() => {
112+
const scope = new EffectScope(() => {
126113
effect(() => (dummy = counter.num))
127114
})
128115

129-
expect(scope._scope.effects.length).toBe(1)
116+
expect(scope.effects.length).toBe(1)
130117

131-
extendScope(scope, () => {
118+
scope.extend(() => {
132119
effect(() => (doubled = counter.num * 2))
133120
})
134121

135-
expect(scope._scope.effects.length).toBe(2)
122+
expect(scope.effects.length).toBe(2)
136123

137124
counter.num = 7
138125
expect(dummy).toBe(7)
139126
expect(doubled).toBe(14)
140127

141-
stop(scope)
128+
scope.stop()
142129
})
143130

144131
it('can not extend an inactive scope', () => {
145132
let dummy, doubled
146133
const counter = reactive({ num: 0 })
147134

148-
const scope = effectScope(() => {
135+
const scope = new EffectScope(() => {
149136
effect(() => (dummy = counter.num))
150137
})
151138

152-
expect(scope._scope.effects.length).toBe(1)
139+
expect(scope.effects.length).toBe(1)
153140

154-
stop(scope)
141+
scope.stop()
155142

156-
extendScope(scope, () => {
143+
scope.extend(() => {
157144
effect(() => (doubled = counter.num * 2))
158145
})
159146

160-
expect('[Vue warn] can not extend on an inactive scope.').toHaveBeenWarned()
147+
expect(
148+
'[Vue warn] cannot extend an inactive effect scope.'
149+
).toHaveBeenWarned()
161150

162-
expect(scope._scope.effects.length).toBe(1)
151+
expect(scope.effects.length).toBe(1)
163152

164153
counter.num = 7
165154
expect(dummy).toBe(0)
@@ -169,80 +158,36 @@ describe('reactivity/effect/scope', () => {
169158
it('should fire onStop hook', () => {
170159
let dummy = 0
171160

172-
const scope = effectScope(onStop => {
161+
const scope = new EffectScope(onStop => {
173162
onStop(() => (dummy += 1))
174163
onStop(() => (dummy += 2))
175164
})
176165

177-
extendScope(scope, onStop => {
166+
scope.extend(onStop => {
178167
onStop(() => (dummy += 4))
179168
})
180169

181170
expect(dummy).toBe(0)
182171

183-
stop(scope)
172+
scope.stop()
184173
expect(dummy).toBe(7)
185174
})
186175

187176
it('should fire onScopeStopped hook', () => {
188177
let dummy = 0
189178

190-
const scope = effectScope(() => {
191-
onScopeStopped(() => (dummy += 1))
192-
onScopeStopped(() => (dummy += 2))
179+
const scope = new EffectScope(() => {
180+
onDispose(() => (dummy += 1))
181+
onDispose(() => (dummy += 2))
193182
})
194183

195-
extendScope(scope, () => {
196-
onScopeStopped(() => (dummy += 4))
184+
scope.extend(() => {
185+
onDispose(() => (dummy += 4))
197186
})
198187

199188
expect(dummy).toBe(0)
200189

201-
stop(scope)
190+
scope.stop()
202191
expect(dummy).toBe(7)
203192
})
204-
205-
it('should forward returns', () => {
206-
let foo = ref(1)
207-
208-
const scope = effectScope(() => {
209-
return {
210-
doubled: computed(() => foo.value * 2)
211-
}
212-
})
213-
214-
const { doubled } = scope
215-
216-
expect(doubled.value).toBe(2)
217-
218-
foo.value += 1
219-
expect(doubled.value).toBe(4)
220-
221-
stop(scope)
222-
223-
foo.value += 1
224-
expect(doubled.value).toBe(4)
225-
})
226-
227-
it('should forward returns on extending', () => {
228-
let foo = ref(1)
229-
230-
const scope = effectScope()
231-
232-
const { tripled } = extendScope(scope, () => {
233-
return {
234-
tripled: computed(() => foo.value * 3)
235-
}
236-
})
237-
238-
expect(tripled.value).toBe(3)
239-
240-
foo.value += 1
241-
expect(tripled.value).toBe(6)
242-
243-
stop(scope)
244-
245-
foo.value += 1
246-
expect(tripled.value).toBe(6)
247-
})
248193
})

packages/reactivity/src/effect.ts

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { TrackOpTypes, TriggerOpTypes } from './operations'
22
import { extend, isArray, isIntegerKey, isMap } from '@vue/shared'
3-
import {
4-
EffectScope,
5-
EffectScopeReturns,
6-
isEffectScope,
7-
isEffectScopeReturns,
8-
recordEffectScope
9-
} from './effectScope'
3+
import { EffectScope, recordEffectScope } from './effectScope'
104

115
// The main WeakMap that stores {target -> key -> dep} connections.
126
// Conceptually, it's easier to think of a dependency as a Dep class
@@ -50,7 +44,7 @@ export class ReactiveEffect<T = any> {
5044
constructor(
5145
public fn: () => T,
5246
public scheduler: EffectScheduler | null = null,
53-
public scope?: EffectScope | null,
47+
scope?: EffectScope | null,
5448
// allow recursive self-invocation
5549
public allowRecurse = false
5650
) {
@@ -70,8 +64,7 @@ export class ReactiveEffect<T = any> {
7064
} finally {
7165
effectStack.pop()
7266
resetTracking()
73-
const n = effectStack.length
74-
activeEffect = n > 0 ? effectStack[n - 1] : undefined
67+
activeEffect = effectStack[effectStack.length - 1]
7568
}
7669
}
7770
}
@@ -133,25 +126,8 @@ export function effect<T = any>(
133126
return runner
134127
}
135128

136-
export function stop(
137-
runner:
138-
| ReactiveEffect
139-
| ReactiveEffectRunner
140-
| EffectScope
141-
| EffectScopeReturns
142-
) {
143-
if (isEffectScopeReturns(runner)) {
144-
runner = runner._scope
145-
}
146-
if (isEffectScope(runner)) {
147-
runner.effects.forEach(stop)
148-
runner.onStopHooks.forEach(e => e(runner as EffectScope))
149-
runner.active = false
150-
} else if ('effect' in runner) {
151-
runner.effect.stop()
152-
} else {
153-
runner.stop()
154-
}
129+
export function stop(runner: ReactiveEffectRunner) {
130+
runner.effect.stop()
155131
}
156132

157133
let shouldTrack = true

0 commit comments

Comments
 (0)