Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(runtime-core): ensure jobs are in the correct order #7622

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/runtime-core/__tests__/scheduler.spec.ts
Original file line number Diff line number Diff line change
@@ -144,6 +144,7 @@ describe('scheduler', () => {
queueJob(job1)
// cb2 should execute before the job
queueJob(cb2)
queueJob(cb3)
}
cb1.pre = true

@@ -153,9 +154,15 @@ 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('preFlushCb inside queueJob', async () => {
25 changes: 20 additions & 5 deletions packages/runtime-core/src/scheduler.ts
Original file line number Diff line number Diff line change
@@ -62,15 +62,30 @@ export function nextTick<T = void>(
// Use binary-search to find a suitable position in the queue,
// so that the queue maintains the increasing order of job's id,
// which can prevent the job from being skipped and also can avoid repeated patching.
function findInsertionIndex(id: number) {
function findInsertionIndex(job: SchedulerJob) {
// the start index should be `flushIndex + 1`
let start = flushIndex + 1
let end = queue.length

const id = getId(job)
const pre = job.pre
let middle
while (start < end) {
const middle = (start + end) >>> 1
middle = (start + end) >>> 1
const middleJobId = getId(queue[middle])
middleJobId < id ? (start = middle + 1) : (end = middle)
if (middleJobId === id) {
while (
queue[middle] &&
getId(queue[middle]) === id &&
(pre ? queue[middle].pre : true)
) {
pre ? middle++ : middle--
}
return middle
} else if (middleJobId < id!) {
start = middle + 1
} else {
end = middle
}
}

return start
@@ -93,7 +108,7 @@ export function queueJob(job: SchedulerJob) {
if (job.id == null) {
queue.push(job)
} else {
queue.splice(findInsertionIndex(job.id), 0, job)
queue.splice(findInsertionIndex(job), 0, job)
}
queueFlush()
}