From d5837e698983b0ecd40bc710bdab5a836ae7a200 Mon Sep 17 00:00:00 2001 From: skirtle <65301168+skirtles-code@users.noreply.github.com> Date: Fri, 17 Feb 2023 13:08:39 +0000 Subject: [PATCH 1/2] fix(runtime-core): pre jobs without an id should run first --- packages/runtime-core/__tests__/scheduler.spec.ts | 10 +++++++++- packages/runtime-core/src/scheduler.ts | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 48bc469716c..7ea38642e18 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -395,12 +395,20 @@ describe('scheduler', () => { job2.id = 2 const job3 = () => calls.push('job3') job3.id = 1 + const job4 = () => calls.push('job4') + job4.id = 2 + job4.pre = true + const job5 = () => calls.push('job5') + // job5 has no id + job5.pre = true queueJob(job1) queueJob(job2) queueJob(job3) + queueJob(job4) + queueJob(job5) await nextTick() - expect(calls).toEqual(['job3', 'job2', 'job1']) + expect(calls).toEqual(['job5', 'job3', 'job4', 'job2', 'job1']) }) test('sort SchedulerCbs based on id', async () => { diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 923f3ec8251..57ec07f3a97 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -191,7 +191,7 @@ export function flushPostFlushCbs(seen?: CountMap) { } const getId = (job: SchedulerJob): number => - job.id == null ? Infinity : job.id + job.id == null ? (job.pre ? -1 : Infinity) : job.id const comparator = (a: SchedulerJob, b: SchedulerJob): number => { const diff = getId(a) - getId(b) From a069dd0722043e2063b7c5e62edb48b1dad6011e Mon Sep 17 00:00:00 2001 From: skirtle <65301168+skirtles-code@users.noreply.github.com> Date: Mon, 20 Feb 2023 10:19:00 +0000 Subject: [PATCH 2/2] fix(runtime-core): id-less pre job insertion during flushing --- .../runtime-core/__tests__/scheduler.spec.ts | 31 +++++++++++++++++++ packages/runtime-core/src/scheduler.ts | 14 ++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 7ea38642e18..8207cad15da 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -186,6 +186,37 @@ describe('scheduler', () => { expect(calls).toEqual(['cb1', 'cb2', 'job1']) }) + it('should insert pre jobs without ids first during flushing', async () => { + const calls: string[] = [] + const job1 = () => { + calls.push('job1') + queueJob(job3) + queueJob(job4) + } + // job1 has no id + job1.pre = true + const job2 = () => { + calls.push('job2') + } + job2.id = 1 + job2.pre = true + const job3 = () => { + calls.push('job3') + } + // job3 has no id + job3.pre = true + const job4 = () => { + calls.push('job4') + } + // job4 has no id + job4.pre = true + + queueJob(job1) + queueJob(job2) + await nextTick() + expect(calls).toEqual(['job1', 'job3', 'job4', 'job2']) + }) + // #3806 it('queue preFlushCb inside postFlushCb', async () => { const spy = vi.fn() diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 57ec07f3a97..efd0ab678fe 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -69,8 +69,13 @@ function findInsertionIndex(id: number) { while (start < end) { const middle = (start + end) >>> 1 - const middleJobId = getId(queue[middle]) - middleJobId < id ? (start = middle + 1) : (end = middle) + const middleJob = queue[middle] + const middleJobId = getId(middleJob) + if (middleJobId < id || (middleJobId === id && middleJob.pre)) { + start = middle + 1 + } else { + end = middle + } } return start @@ -90,10 +95,11 @@ export function queueJob(job: SchedulerJob) { isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex ) ) { - if (job.id == null) { + const jobId = getId(job) + if (jobId === Infinity) { queue.push(job) } else { - queue.splice(findInsertionIndex(job.id), 0, job) + queue.splice(findInsertionIndex(jobId), 0, job) } queueFlush() }