fix(scheduler): ensure updates are always inserted in ascending id order (#3184)

fix #2768, fix #2829
This commit is contained in:
HcySunYang
2021-02-25 22:37:25 +08:00
committed by GitHub
parent 75964aba03
commit 45fae9d308
2 changed files with 57 additions and 1 deletions

View File

@@ -57,6 +57,25 @@ export function nextTick(
return fn ? p.then(this ? fn.bind(this) : fn) : p
}
// #2768
// 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(job: SchedulerJob) {
// the start index should be `flushIndex + 1`
let start = flushIndex + 1
let end = queue.length
const jobId = getId(job)
while (start < end) {
const middle = (start + end) >>> 1
const middleJobId = getId(queue[middle])
middleJobId < jobId ? (start = middle + 1) : (end = middle)
}
return start
}
export function queueJob(job: SchedulerJob) {
// the dedupe search uses the startIndex argument of Array.includes()
// by default the search index includes the current job that is being run
@@ -72,7 +91,12 @@ export function queueJob(job: SchedulerJob) {
)) &&
job !== currentPreFlushParentJob
) {
queue.push(job)
const pos = findInsertionIndex(job)
if (pos > -1) {
queue.splice(pos, 0, job)
} else {
queue.push(job)
}
queueFlush()
}
}