]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(scheduler): prevent duplicate jobs being queued (#11826)
authorskirtle <65301168+skirtles-code@users.noreply.github.com>
Thu, 5 Sep 2024 12:51:26 +0000 (13:51 +0100)
committerGitHub <noreply@github.com>
Thu, 5 Sep 2024 12:51:26 +0000 (20:51 +0800)
Fix #11712
Fix #11807

packages/runtime-core/src/scheduler.ts

index 727eb14e310ec48ae88b055b8a41ff21912345f2..2250af41110704cf64b6ddb7c1c308ea0ffcefff 100644 (file)
@@ -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