Skip to content

Commit

Permalink
fix(reactivity): release nested effects/scopes on effect scope stop (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
edison1105 authored Nov 14, 2024
1 parent 2193284 commit bee2f5e
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
5 changes: 4 additions & 1 deletion packages/reactivity/__tests__/effectScope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ describe('reactivity/effect/scope', () => {

expect('[Vue warn] cannot run an inactive effect scope.').toHaveBeenWarned()

expect(scope.effects.length).toBe(1)
expect(scope.effects.length).toBe(0)

counter.num = 7
expect(dummy).toBe(0)
Expand Down Expand Up @@ -358,5 +358,8 @@ describe('reactivity/effect/scope', () => {
await nextTick()
expect(watcherCalls).toBe(3)
expect(cleanupCalls).toBe(1)

expect(scope.effects.length).toBe(0)
expect(scope.cleanups.length).toBe(0)
})
})
11 changes: 9 additions & 2 deletions packages/reactivity/src/effectScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,24 @@ export class EffectScope {
if (this._active) {
this._active = false
let i, l
for (i = 0, l = this.effects.length; i < l; i++) {
this.effects[i].stop()
const effects = this.effects.slice()
for (i = 0, l = effects.length; i < l; i++) {
effects[i].stop()
}
this.effects.length = 0

for (i = 0, l = this.cleanups.length; i < l; i++) {
this.cleanups[i]()
}
this.cleanups.length = 0

if (this.scopes) {
for (i = 0, l = this.scopes.length; i < l; i++) {
this.scopes[i].stop(true)
}
this.scopes.length = 0
}

// nested scope, dereference from parent to avoid memory leaks
if (!this.detached && this.parent && !fromParent) {
// optimized O(1) removal
Expand Down
3 changes: 1 addition & 2 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
} from '@vue/runtime-test'
import {
type DebuggerEvent,
EffectFlags,
ITERATE_KEY,
type Ref,
type ShallowRef,
Expand Down Expand Up @@ -1341,7 +1340,7 @@ describe('api: watch', () => {
await nextTick()
await nextTick()

expect(instance!.scope.effects[0].flags & EffectFlags.ACTIVE).toBeFalsy()
expect(instance!.scope.effects.length).toBe(0)
})

test('this.$watch should pass `this.proxy` to watch source as the first argument ', () => {
Expand Down

0 comments on commit bee2f5e

Please sign in to comment.