diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 5c5b04673ab..e85e0942ae6 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -644,4 +644,27 @@ describe('scheduler', () => { await nextTick() expect(calls).toEqual(['cb2', 'cb1']) }) + + test('nextick callback should be executed after the queuejob', async () => { + let val = 1 + queueJob(() => { + val = 3 + }) + await nextTick(() => { + val = 2 + }) + expect(val).toBe(2) + + const p = new Promise(r => { + nextTick(() => { + val = 2 + r() + }) + queueJob(() => { + val = 3 + }) + }) + await p + expect(val).toBe(2) + }) }) diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 1eac06e5bf0..5a57aa30e2b 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -61,7 +61,17 @@ export function nextTick( fn?: (this: T) => R, ): Promise> { const p = currentFlushPromise || resolvedPromise - return fn ? p.then(this ? fn.bind(this) : fn) : p + let wrapperFn: ((this: T) => R | Promise | undefined) | undefined = fn + if (!currentFlushPromise) { + wrapperFn = function () { + if (!fn) return + if (currentFlushPromise) { + return currentFlushPromise.then(fn.bind(this)) + } + return fn.call(this) + } + } + return wrapperFn ? p.then(this ? wrapperFn.bind(this) : wrapperFn) : p } // Use binary-search to find a suitable position in the queue. The queue needs