]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix: fix scheduler dupe invokes
authorEvan You <yyx990803@gmail.com>
Mon, 24 Sep 2018 17:38:54 +0000 (13:38 -0400)
committerEvan You <yyx990803@gmail.com>
Mon, 24 Sep 2018 17:38:54 +0000 (13:38 -0400)
packages/core/src/createRenderer.ts
packages/scheduler/__tests__/scheduler.spec.ts
packages/scheduler/src/index.ts

index 1deb16305b6338211d1227b3c32bd156054b62e9..3d9af821394945eae60cff73b7b7c581b4281bc6 100644 (file)
@@ -160,10 +160,6 @@ export function createRenderer(options: RendererOptions) {
 
   const hooks: Function[] = []
 
-  function queueHook(fn: Function) {
-    hooks.push(fn)
-  }
-
   function flushHooks() {
     let fn
     while ((fn = hooks.shift())) {
@@ -251,7 +247,7 @@ export function createRenderer(options: RendererOptions) {
   }
 
   function mountRef(ref: Ref, el: RenderNode | MountedComponent) {
-    queueHook(() => {
+    hooks.push(() => {
       ref(el)
     })
   }
@@ -1166,8 +1162,9 @@ export function createRenderer(options: RendererOptions) {
         }
       },
       {
-        scheduler: queueUpdate
-        // TODO add API for using onTrigger for component re-render debugging
+        scheduler: queueUpdate,
+        onTrack: instance.renderTracked,
+        onTrigger: instance.renderTriggered
       }
     )
 
@@ -1185,7 +1182,7 @@ export function createRenderer(options: RendererOptions) {
       mountRef(ref, instance)
     }
     if (instance.mounted) {
-      queueHook(() => {
+      hooks.push(() => {
         ;(instance as any).mounted.call(instance.$proxy)
       })
     }
@@ -1220,7 +1217,12 @@ export function createRenderer(options: RendererOptions) {
     }
 
     if (instance.updated) {
-      queueHook(() => {
+      // Because the child's update is executed by the scheduler and not
+      // synchronously within the parent's update call, the child's updated hook
+      // will be added to the queue AFTER the parent's, but they should be
+      // invoked BEFORE the parent's. Therefore we add them to the head of the
+      // queue instead.
+      hooks.unshift(() => {
         ;(instance as any).updated.call(instance.$proxy, nextVNode)
       })
     }
index fccd4ffd2151bca5aeb46621bc04dc73617419a6..a0aa89fd52c40a6a8a717ac17268eb485386726f 100644 (file)
@@ -22,8 +22,6 @@ describe('scheduler', () => {
       calls.push('job1')
       // job1 queues job2
       queueJob(job2)
-      // should be called sync
-      expect(calls).toEqual(['job1', 'job2'])
     }
     const job2 = () => {
       calls.push('job2')
@@ -60,8 +58,6 @@ describe('scheduler', () => {
       calls.push('job1')
       // job1 queues job2
       queueJob(job2, cb2)
-      // should be called sync
-      expect(calls).toEqual(['job1', 'job2'])
     }
     const job2 = () => {
       calls.push('job2')
index e99840be786f62aa1b74cbe97d455b898ea8fbf4..93172ffdd5c0874020ddebc021b275d71bc323cd 100644 (file)
@@ -2,7 +2,7 @@ const queue: Array<() => void> = []
 const postFlushCbs: Array<() => void> = []
 const p = Promise.resolve()
 
-let flushing = false
+let hasPendingFlush = false
 
 export function nextTick(fn?: () => void): Promise<void> {
   return p.then(fn)
@@ -10,22 +10,18 @@ export function nextTick(fn?: () => void): Promise<void> {
 
 export function queueJob(job: () => void, postFlushCb?: () => void) {
   if (queue.indexOf(job) === -1) {
-    if (flushing) {
-      job()
-    } else {
-      queue.push(job)
+    queue.push(job)
+    if (!hasPendingFlush) {
+      hasPendingFlush = true
+      nextTick(flushJobs)
     }
   }
-  if (postFlushCb) {
+  if (postFlushCb && postFlushCbs.indexOf(postFlushCb) === -1) {
     postFlushCbs.push(postFlushCb)
   }
-  if (!flushing) {
-    nextTick(flushJobs)
-  }
 }
 
 function flushJobs() {
-  flushing = true
   let job
   while ((job = queue.shift())) {
     job()
@@ -33,5 +29,5 @@ function flushJobs() {
   while ((job = postFlushCbs.shift())) {
     job()
   }
-  flushing = false
+  hasPendingFlush = false
 }