]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(runtime-core): make nextTick() promise reject on scheduler flush error
authorEvan You <yyx990803@gmail.com>
Tue, 28 Jul 2020 04:20:30 +0000 (00:20 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 28 Jul 2020 14:40:25 +0000 (10:40 -0400)
packages/runtime-core/__tests__/scheduler.spec.ts
packages/runtime-core/src/scheduler.ts

index 9e0e104329a96cfbb04acf26e2dc96462908c0b8..cbd349fe812183152feea4086c149308af6e5273 100644 (file)
@@ -294,4 +294,19 @@ describe('scheduler', () => {
     await nextTick()
     expect(calls).toEqual(['cb1', 'cb2'])
   })
+
+  test('nextTick should capture scheduler flush errors', async () => {
+    const err = new Error('test')
+    queueJob(() => {
+      throw err
+    })
+    try {
+      await nextTick()
+    } catch (e) {
+      expect(e).toBe(err)
+    }
+    expect(
+      `Unhandled error during execution of scheduler flush`
+    ).toHaveBeenWarned()
+  })
 })
index 8a775b39341d2a9d151c41162e01bd07df924b10..33743dce639cbe944468581a84ee8e481d59f9f2 100644 (file)
@@ -8,7 +8,8 @@ export interface Job {
 
 const queue: (Job | null)[] = []
 const postFlushCbs: Function[] = []
-const p = Promise.resolve()
+const resolvedPromise: Promise<any> = Promise.resolve()
+let currentFlushPromise: Promise<void> | null = null
 
 let isFlushing = false
 let isFlushPending = false
@@ -20,6 +21,7 @@ const RECURSION_LIMIT = 100
 type CountMap = Map<Job | Function, number>
 
 export function nextTick(fn?: () => void): Promise<void> {
+  const p = currentFlushPromise || resolvedPromise
   return fn ? p.then(fn) : p
 }
 
@@ -57,7 +59,7 @@ export function queuePostFlushCb(cb: Function | Function[]) {
 function queueFlush() {
   if (!isFlushing && !isFlushPending) {
     isFlushPending = true
-    nextTick(flushJobs)
+    currentFlushPromise = resolvedPromise.then(flushJobs)
   }
 }
 
@@ -117,6 +119,7 @@ function flushJobs(seen?: CountMap) {
 
   flushPostFlushCbs(seen)
   isFlushing = false
+  currentFlushPromise = null
   // some postFlushCb queued jobs!
   // keep flushing until it drains.
   if (queue.length || postFlushCbs.length) {