wip: adjust watcher cleanup api

This commit is contained in:
Evan You 2019-06-06 15:19:04 +08:00
parent 1d41771e56
commit d3fe492d7e
2 changed files with 30 additions and 42 deletions

View File

@ -37,21 +37,6 @@ describe('observer/computed', () => {
expect(getter).toHaveBeenCalledTimes(2) expect(getter).toHaveBeenCalledTimes(2)
}) })
it('should accept context', () => {
const value: any = observable({})
let callCtx, callArg
const getter = function(arg: any) {
callCtx = this
callArg = arg
return value.foo
}
const ctx = {}
const cValue = computed(getter, ctx)
cValue.value
expect(callCtx).toBe(ctx)
expect(callArg).toBe(ctx)
})
it('should trigger effect', () => { it('should trigger effect', () => {
const value: any = observable({}) const value: any = observable({})
const cValue = computed(() => value.foo) const cValue = computed(() => value.foo)
@ -136,4 +121,8 @@ describe('observer/computed', () => {
value.foo = 2 value.foo = 2
expect(dummy).toBe(1) expect(dummy).toBe(1)
}) })
it('should support setter', () => {
// TODO
})
}) })

View File

@ -31,7 +31,7 @@ import {
} from '@vue/observer' } from '@vue/observer'
import { currentInstance } from './component' import { currentInstance } from './component'
import { queueJob, queuePostFlushCb } from './scheduler' import { queueJob, queuePostFlushCb } from './scheduler'
import { EMPTY_OBJ, isObject, isArray, isFunction } from '@vue/shared' import { EMPTY_OBJ, isObject, isArray } from '@vue/shared'
// record effects created during a component's setup() so that they can be // record effects created during a component's setup() so that they can be
// stopped when the component unmounts // stopped when the component unmounts
@ -63,39 +63,38 @@ const invoke = (fn: Function) => fn()
export function watch<T>( export function watch<T>(
source: Value<T> | (() => T), source: Value<T> | (() => T),
cb?: <V extends T>(newValue: V, oldValue: V) => (() => void) | void, cb?: <V extends T>(
options: WatchOptions = EMPTY_OBJ newValue: V,
oldValue: V,
onInvalidate: (fn: () => void) => void
) => any | void,
{ lazy, flush, deep, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
): () => void { ): () => void {
const scheduler = const scheduler =
options.flush === 'sync' flush === 'sync' ? invoke : flush === 'pre' ? queueJob : queuePostFlushCb
? invoke
: options.flush === 'pre'
? queueJob
: queuePostFlushCb
const baseGetter = isValue(source) ? () => source.value : source const baseGetter = isValue(source) ? () => source.value : source
const getter = options.deep ? () => traverse(baseGetter()) : baseGetter const getter = deep ? () => traverse(baseGetter()) : baseGetter
let cleanup: any
const registerCleanup = (fn: () => void) => {
// TODO wrap the cleanup fn for error handling
cleanup = runner.onStop = fn
}
let oldValue: any let oldValue: any
let cleanup: any
const applyCb = cb const applyCb = cb
? () => { ? () => {
const newValue = runner() const newValue = runner()
if (options.deep || newValue !== oldValue) { if (deep || newValue !== oldValue) {
try {
// cleanup before running cb again // cleanup before running cb again
if (cleanup) { if (cleanup) {
cleanup() cleanup()
} }
const _cleanup = cb(newValue, oldValue) // TODO handle error (including ASYNC)
if (isFunction(_cleanup)) { try {
// save cleanup so it is also called when effect is stopped cb(newValue, oldValue, registerCleanup)
cleanup = runner.onStop = _cleanup } catch (e) {}
}
} catch (e) {
// TODO handle error
// handleError(e, instance, ErrorTypes.WATCH_CALLBACK)
}
oldValue = newValue oldValue = newValue
} }
} }
@ -105,12 +104,12 @@ export function watch<T>(
lazy: true, lazy: true,
// so it runs before component update effects in pre flush mode // so it runs before component update effects in pre flush mode
computed: true, computed: true,
onTrack: options.onTrack, onTrack,
onTrigger: options.onTrigger, onTrigger,
scheduler: applyCb ? () => scheduler(applyCb) : void 0 scheduler: applyCb ? () => scheduler(applyCb) : void 0
}) })
if (!options.lazy) { if (!lazy) {
applyCb && scheduler(applyCb) applyCb && scheduler(applyCb)
} else { } else {
oldValue = runner() oldValue = runner()