Răsfoiți Sursa

wip: watcher cleanup improvement

Evan You 7 ani în urmă
părinte
comite
1d41771e56

+ 3 - 0
packages/observer/src/effect.ts

@@ -11,6 +11,7 @@ export interface ReactiveEffect {
   scheduler?: Scheduler
   onTrack?: Debugger
   onTrigger?: Debugger
+  onStop?: () => void
 }
 
 export interface ReactiveEffectOptions {
@@ -19,6 +20,7 @@ export interface ReactiveEffectOptions {
   scheduler?: Scheduler
   onTrack?: Debugger
   onTrigger?: Debugger
+  onStop?: () => void
 }
 
 export type Scheduler = (run: () => any) => void
@@ -49,6 +51,7 @@ export function createReactiveEffect(
   effect.scheduler = options.scheduler
   effect.onTrack = options.onTrack
   effect.onTrigger = options.onTrigger
+  effect.onStop = options.onStop
   effect.computed = options.computed
   effect.deps = []
   return effect

+ 3 - 0
packages/observer/src/index.ts

@@ -134,6 +134,9 @@ export function effect(
 export function stop(effect: ReactiveEffect) {
   if (effect.active) {
     cleanup(effect)
+    if (effect.onStop) {
+      effect.onStop()
+    }
     effect.active = false
   }
 }

+ 7 - 2
packages/runtime-core/src/reactivity.ts

@@ -83,10 +83,15 @@ export function watch<T>(
         const newValue = runner()
         if (options.deep || newValue !== oldValue) {
           try {
-            if (isFunction(cleanup)) {
+            // cleanup before running cb again
+            if (cleanup) {
               cleanup()
             }
-            cleanup = cb(newValue, oldValue)
+            const _cleanup = cb(newValue, oldValue)
+            if (isFunction(_cleanup)) {
+              // save cleanup so it is also called when effect is stopped
+              cleanup = runner.onStop = _cleanup
+            }
           } catch (e) {
             // TODO handle error
             // handleError(e, instance, ErrorTypes.WATCH_CALLBACK)