await nextTick()
expect(calls).toEqual(['job1', 'job2', 'cb1', 'cb2'])
})
+
+ test('jobs added during post flush are ordered correctly', async () => {
+ const calls: string[] = []
+
+ const job1: SchedulerJob = () => {
+ calls.push('job1')
+ }
+ job1.id = 1
+
+ const job2: SchedulerJob = () => {
+ calls.push('job2')
+ }
+ job2.id = 2
+
+ queuePostFlushCb(() => {
+ queueJob(job2)
+ queueJob(job1)
+ })
+
+ await nextTick()
+
+ expect(calls).toEqual(['job1', 'job2'])
+ })
})
test('sort job based on id', async () => {
expect(spy).toHaveBeenCalledTimes(1)
})
+ test('flushPreFlushCbs inside a post job', async () => {
+ const calls: string[] = []
+ const callsAfterFlush: string[] = []
+
+ const job1: SchedulerJob = () => {
+ calls.push('job1')
+ }
+ job1.id = 1
+ job1.flags! |= SchedulerJobFlags.PRE
+
+ const job2: SchedulerJob = () => {
+ calls.push('job2')
+ }
+ job2.id = 2
+ job2.flags! |= SchedulerJobFlags.PRE
+
+ queuePostFlushCb(() => {
+ queueJob(job2)
+ queueJob(job1)
+
+ // e.g. nested app.mount() call
+ flushPreFlushCbs()
+ callsAfterFlush.push(...calls)
+ })
+
+ await nextTick()
+
+ expect(callsAfterFlush).toEqual(['job1', 'job2'])
+ expect(calls).toEqual(['job1', 'job2'])
+ })
+
it('nextTick should return promise', async () => {
const fn = vi.fn(() => {
return 1
export type SchedulerJobs = SchedulerJob | SchedulerJob[]
-let isFlushing = false
-let isFlushPending = false
-
const queue: SchedulerJob[] = []
-let flushIndex = 0
+let flushIndex = -1
const pendingPostFlushCbs: SchedulerJob[] = []
let activePostFlushCbs: SchedulerJob[] | null = null
// watcher should be inserted immediately before the update job. This allows
// watchers to be skipped if the component is unmounted by the parent update.
function findInsertionIndex(id: number) {
- let start = isFlushing ? flushIndex + 1 : 0
+ let start = flushIndex + 1
let end = queue.length
while (start < end) {
}
function queueFlush() {
- if (!isFlushing && !isFlushPending) {
- isFlushPending = true
+ if (!currentFlushPromise) {
currentFlushPromise = resolvedPromise.then(flushJobs)
}
}
export function flushPreFlushCbs(
instance?: ComponentInternalInstance,
seen?: CountMap,
- // if currently flushing, skip the current job itself
- i: number = isFlushing ? flushIndex + 1 : 0,
+ // skip the current job
+ i: number = flushIndex + 1,
): void {
if (__DEV__) {
seen = seen || new Map()
job.id == null ? (job.flags! & SchedulerJobFlags.PRE ? -1 : Infinity) : job.id
function flushJobs(seen?: CountMap) {
- isFlushPending = false
- isFlushing = true
if (__DEV__) {
seen = seen || new Map()
}
}
}
- flushIndex = 0
+ flushIndex = -1
queue.length = 0
flushPostFlushCbs(seen)
- isFlushing = false
currentFlushPromise = null
- // some postFlushCb queued jobs!
- // keep flushing until it drains.
+ // If new jobs have been added to either queue, keep flushing
if (queue.length || pendingPostFlushCbs.length) {
flushJobs(seen)
}