]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(scheduler): ensure jobs are in the correct order (#7748)
authorskirtle <65301168+skirtles-code@users.noreply.github.com>
Sat, 21 Oct 2023 02:38:54 +0000 (03:38 +0100)
committerGitHub <noreply@github.com>
Sat, 21 Oct 2023 02:38:54 +0000 (10:38 +0800)
close #7576

packages/runtime-core/__tests__/scheduler.spec.ts
packages/runtime-core/src/scheduler.ts

index 6246a87e8f73435e3444635cf5420bfab22e05b9..119d0f7080c0cf11af31bbdb5938e7a84b8bad81 100644 (file)
@@ -143,6 +143,7 @@ describe('scheduler', () => {
         queueJob(job1)
         // cb2 should execute before the job
         queueJob(cb2)
+        queueJob(cb3)
       }
       cb1.pre = true
 
@@ -152,9 +153,60 @@ describe('scheduler', () => {
       cb2.pre = true
       cb2.id = 1
 
+      const cb3 = () => {
+        calls.push('cb3')
+      }
+      cb3.pre = true
+      cb3.id = 1
+
       queueJob(cb1)
       await nextTick()
-      expect(calls).toEqual(['cb1', 'cb2', 'job1'])
+      expect(calls).toEqual(['cb1', 'cb2', 'cb3', 'job1'])
+    })
+
+    it('should insert jobs after pre jobs with the same id', async () => {
+      const calls: string[] = []
+      const job1 = () => {
+        calls.push('job1')
+      }
+      job1.id = 1
+      job1.pre = true
+      const job2 = () => {
+        calls.push('job2')
+        queueJob(job5)
+        queueJob(job6)
+      }
+      job2.id = 2
+      job2.pre = true
+      const job3 = () => {
+        calls.push('job3')
+      }
+      job3.id = 2
+      job3.pre = true
+      const job4 = () => {
+        calls.push('job4')
+      }
+      job4.id = 3
+      job4.pre = true
+      const job5 = () => {
+        calls.push('job5')
+      }
+      job5.id = 2
+      const job6 = () => {
+        calls.push('job6')
+      }
+      job6.id = 2
+      job6.pre = true
+
+      // We need several jobs to test this properly, otherwise
+      // findInsertionIndex can yield the correct index by chance
+      queueJob(job4)
+      queueJob(job2)
+      queueJob(job3)
+      queueJob(job1)
+
+      await nextTick()
+      expect(calls).toEqual(['job1', 'job2', 'job3', 'job6', 'job5', 'job4'])
     })
 
     it('preFlushCb inside queueJob', async () => {
index 64c70ab59ca06fe2b7f0059bc85c5fa71686858b..e4c7fbc0f4d0c54a2a1f7435003f4cd59a6db364 100644 (file)
@@ -69,8 +69,13 @@ function findInsertionIndex(id: number) {
 
   while (start < end) {
     const middle = (start + end) >>> 1
-    const middleJobId = getId(queue[middle])
-    middleJobId < id ? (start = middle + 1) : (end = middle)
+    const middleJob = queue[middle]
+    const middleJobId = getId(middleJob)
+    if (middleJobId < id || (middleJobId === id && middleJob.pre)) {
+      start = middle + 1
+    } else {
+      end = middle
+    }
   }
 
   return start