|
|
@@ -126,6 +126,10 @@ export class ReactiveEffect<T = any>
|
|
|
* @internal
|
|
|
*/
|
|
|
nextEffect?: ReactiveEffect = undefined
|
|
|
+ /**
|
|
|
+ * @internal
|
|
|
+ */
|
|
|
+ cleanup?: () => void = undefined
|
|
|
|
|
|
scheduler?: EffectScheduler = undefined
|
|
|
onStop?: () => void
|
|
|
@@ -165,6 +169,7 @@ export class ReactiveEffect<T = any>
|
|
|
}
|
|
|
|
|
|
this.flags |= EffectFlags.RUNNING
|
|
|
+ cleanupEffect(this)
|
|
|
prepareDeps(this)
|
|
|
const prevEffect = activeSub
|
|
|
const prevShouldTrack = shouldTrack
|
|
|
@@ -193,6 +198,7 @@ export class ReactiveEffect<T = any>
|
|
|
removeSub(link)
|
|
|
}
|
|
|
this.deps = this.depsTail = undefined
|
|
|
+ cleanupEffect(this)
|
|
|
this.onStop && this.onStop()
|
|
|
this.flags &= ~EffectFlags.ACTIVE
|
|
|
}
|
|
|
@@ -479,3 +485,41 @@ export function resetTracking() {
|
|
|
const last = trackStack.pop()
|
|
|
shouldTrack = last === undefined ? true : last
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Registers a cleanup function for the current active effect.
|
|
|
+ * The cleanup function is called right before the next effect run, or when the
|
|
|
+ * effect is stopped.
|
|
|
+ *
|
|
|
+ * Throws a warning iff there is no currenct active effect. The warning can be
|
|
|
+ * suppressed by passing `true` to the second argument.
|
|
|
+ *
|
|
|
+ * @param fn - the cleanup function to be registered
|
|
|
+ * @param failSilently - if `true`, will not throw warning when called without
|
|
|
+ * an active effect.
|
|
|
+ */
|
|
|
+export function onEffectCleanup(fn: () => void, failSilently = false) {
|
|
|
+ if (activeSub instanceof ReactiveEffect) {
|
|
|
+ activeSub.cleanup = fn
|
|
|
+ } else if (__DEV__ && !failSilently) {
|
|
|
+ warn(
|
|
|
+ `onEffectCleanup() was called when there was no active effect` +
|
|
|
+ ` to associate with.`,
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function cleanupEffect(e: ReactiveEffect) {
|
|
|
+ const { cleanup } = e
|
|
|
+ e.cleanup = undefined
|
|
|
+ if (cleanup) {
|
|
|
+ // run cleanup without active effect
|
|
|
+ const prevSub = activeSub
|
|
|
+ activeSub = undefined
|
|
|
+ try {
|
|
|
+ cleanup()
|
|
|
+ } finally {
|
|
|
+ activeSub = prevSub
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|