Explorar el Código

fix(scheduler): recover nextTick from error in post flush cb

Evan You hace 1 año
padre
commit
2bbb6d2fc5

+ 8 - 0
packages/runtime-core/__tests__/scheduler.spec.ts

@@ -844,4 +844,12 @@ describe('scheduler', () => {
     await nextTick()
     expect(calls).toEqual(['cb2', 'cb1'])
   })
+
+  test('error in postFlush cb should not cause nextTick to stuck in rejected state forever', async () => {
+    queuePostFlushCb(() => {
+      throw 'err'
+    })
+    await expect(nextTick).rejects.toThrow('err')
+    await expect(nextTick()).resolves.toBeUndefined()
+  })
 })

+ 11 - 3
packages/runtime-core/src/scheduler.ts

@@ -119,7 +119,10 @@ export function queueJob(job: SchedulerJob): void {
 
 function queueFlush() {
   if (!currentFlushPromise) {
-    currentFlushPromise = resolvedPromise.then(flushJobs)
+    currentFlushPromise = resolvedPromise.then(flushJobs).catch(e => {
+      currentFlushPromise = null
+      throw e
+    })
   }
 }
 
@@ -201,8 +204,13 @@ export function flushPostFlushCbs(seen?: CountMap): void {
       if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) {
         cb.flags! &= ~SchedulerJobFlags.QUEUED
       }
-      if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) cb()
-      cb.flags! &= ~SchedulerJobFlags.QUEUED
+      if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) {
+        try {
+          cb()
+        } finally {
+          cb.flags! &= ~SchedulerJobFlags.QUEUED
+        }
+      }
     }
     activePostFlushCbs = null
     postFlushIndex = 0