From c23c01f1ede0ca50d6a2e401e5d571659bbbd760 Mon Sep 17 00:00:00 2001 From: skirtle <65301168+skirtles-code@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:47:09 +0100 Subject: [PATCH] fix(scheduler): prevent duplicate jobs being queued --- packages/runtime-core/src/scheduler.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 727eb14e310..2250af41110 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -108,9 +108,8 @@ export function queueJob(job: SchedulerJob): void { queue.splice(findInsertionIndex(jobId), 0, job) } - if (!(job.flags! & SchedulerJobFlags.ALLOW_RECURSE)) { - job.flags! |= SchedulerJobFlags.QUEUED - } + job.flags! |= SchedulerJobFlags.QUEUED + queueFlush() } } @@ -128,9 +127,7 @@ export function queuePostFlushCb(cb: SchedulerJobs): void { activePostFlushCbs.splice(postFlushIndex + 1, 0, cb) } else if (!(cb.flags! & SchedulerJobFlags.QUEUED)) { pendingPostFlushCbs.push(cb) - if (!(cb.flags! & SchedulerJobFlags.ALLOW_RECURSE)) { - cb.flags! |= SchedulerJobFlags.QUEUED - } + cb.flags! |= SchedulerJobFlags.QUEUED } } else { // if cb is an array, it is a component lifecycle hook which can only be @@ -161,6 +158,9 @@ export function flushPreFlushCbs( } queue.splice(i, 1) i-- + if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) { + cb.flags! &= ~SchedulerJobFlags.QUEUED + } cb() cb.flags! &= ~SchedulerJobFlags.QUEUED } @@ -194,6 +194,9 @@ export function flushPostFlushCbs(seen?: CountMap): void { if (__DEV__ && checkRecursiveUpdates(seen!, cb)) { continue } + if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) { + cb.flags! &= ~SchedulerJobFlags.QUEUED + } if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) cb() cb.flags! &= ~SchedulerJobFlags.QUEUED } @@ -228,6 +231,9 @@ function flushJobs(seen?: CountMap) { if (__DEV__ && check(job)) { continue } + if (job.flags! & SchedulerJobFlags.ALLOW_RECURSE) { + job.flags! &= ~SchedulerJobFlags.QUEUED + } callWithErrorHandling( job, job.i, @@ -237,6 +243,14 @@ function flushJobs(seen?: CountMap) { } } } finally { + // If there was an error we still need to clear the QUEUED flags + for (; flushIndex < queue.length; flushIndex++) { + const job = queue[flushIndex] + if (job) { + job.flags! &= ~SchedulerJobFlags.QUEUED + } + } + flushIndex = 0 queue.length = 0