Просмотр исходного кода

fix(scheduler): prevent duplicate jobs being queued (#11826)

Fix #11712
Fix #11807
skirtle 1 год назад
Родитель
Сommit
df56cc5287
1 измененных файлов с 20 добавлено и 6 удалено
  1. 20 6
      packages/runtime-core/src/scheduler.ts

+ 20 - 6
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