diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index c396452b..90ebe02a 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -77,9 +77,6 @@ function doWatch( | null, { lazy, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ ): StopHandle { - const scheduler = - flush === 'sync' ? invoke : flush === 'pre' ? queueJob : queuePostFlushCb - const baseGetter = isArray(source) ? () => source.map(s => (isRef(s) ? s.value : s())) : isRef(source) @@ -111,17 +108,24 @@ function doWatch( } : void 0 + const scheduler = + flush === 'sync' ? invoke : flush === 'pre' ? queueJob : queuePostFlushCb + const runner = effect(getter, { lazy: true, // so it runs before component update effects in pre flush mode computed: true, onTrack, onTrigger, - scheduler: applyCb ? () => scheduler(applyCb) : void 0 + scheduler: applyCb ? () => scheduler(applyCb) : scheduler }) if (!lazy) { - applyCb && scheduler(applyCb) + if (applyCb) { + scheduler(applyCb) + } else { + scheduler(runner) + } } else { oldValue = runner() } diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 978e5320..a81ecdff 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -8,22 +8,32 @@ export function nextTick(fn?: () => void): Promise { return fn ? p.then(fn) : p } -export function queueJob(job: () => void, onError?: (err: Error) => void) { +type ErrorHandler = (err: Error) => void + +export function queueJob(job: () => void, onError?: ErrorHandler) { if (queue.indexOf(job) === -1) { queue.push(job) - if (!isFlushing) { - const p = nextTick(flushJobs) - if (onError) p.catch(onError) - } + queueFlush(onError) } } -export function queuePostFlushCb(cb: Function | Function[]) { +export function queuePostFlushCb( + cb: Function | Function[], + onError?: ErrorHandler +) { if (Array.isArray(cb)) { postFlushCbs.push.apply(postFlushCbs, cb) } else { postFlushCbs.push(cb) } + queueFlush(onError) +} + +function queueFlush(onError?: ErrorHandler) { + if (!isFlushing) { + const p = nextTick(flushJobs) + if (onError) p.catch(onError) + } } const dedupe = (cbs: Function[]): Function[] => Array.from(new Set(cbs))