@@ -12,6 +12,9 @@ const p = Promise.resolve()
1212
1313let isFlushing = false
1414let isFlushPending = false
15+ let flushIndex = 0
16+ let pendingPostFlushCbs : Function [ ] | null = null
17+ let pendingPostFlushIndex = 0
1518
1619const RECURSION_LIMIT = 100
1720type CountMap = Map < Job | Function , number >
@@ -21,7 +24,7 @@ export function nextTick(fn?: () => void): Promise<void> {
2124}
2225
2326export function queueJob ( job : Job ) {
24- if ( ! queue . includes ( job ) ) {
27+ if ( ! queue . includes ( job , flushIndex ) ) {
2528 queue . push ( job )
2629 queueFlush ( )
2730 }
@@ -36,8 +39,16 @@ export function invalidateJob(job: Job) {
3639
3740export function queuePostFlushCb ( cb : Function | Function [ ] ) {
3841 if ( ! isArray ( cb ) ) {
39- postFlushCbs . push ( cb )
42+ if (
43+ ! pendingPostFlushCbs ||
44+ ! pendingPostFlushCbs . includes ( cb , pendingPostFlushIndex )
45+ ) {
46+ postFlushCbs . push ( cb )
47+ }
4048 } else {
49+ // if cb is an array, it is a component lifecycle hook which can only be
50+ // triggered by a job, which is already deduped in the main queue, so
51+ // we can skip dupicate check here to improve perf
4152 postFlushCbs . push ( ...cb )
4253 }
4354 queueFlush ( )
@@ -52,17 +63,23 @@ function queueFlush() {
5263
5364export function flushPostFlushCbs ( seen ?: CountMap ) {
5465 if ( postFlushCbs . length ) {
55- const cbs = [ ...new Set ( postFlushCbs ) ]
66+ pendingPostFlushCbs = [ ...new Set ( postFlushCbs ) ]
5667 postFlushCbs . length = 0
5768 if ( __DEV__ ) {
5869 seen = seen || new Map ( )
5970 }
60- for ( let i = 0 ; i < cbs . length ; i ++ ) {
71+ for (
72+ pendingPostFlushIndex = 0 ;
73+ pendingPostFlushIndex < pendingPostFlushCbs . length ;
74+ pendingPostFlushIndex ++
75+ ) {
6176 if ( __DEV__ ) {
62- checkRecursiveUpdates ( seen ! , cbs [ i ] )
77+ checkRecursiveUpdates ( seen ! , pendingPostFlushCbs [ pendingPostFlushIndex ] )
6378 }
64- cbs [ i ] ( )
79+ pendingPostFlushCbs [ pendingPostFlushIndex ] ( )
6580 }
81+ pendingPostFlushCbs = null
82+ pendingPostFlushIndex = 0
6683 }
6784}
6885
@@ -71,7 +88,6 @@ const getId = (job: Job) => (job.id == null ? Infinity : job.id)
7188function flushJobs ( seen ?: CountMap ) {
7289 isFlushPending = false
7390 isFlushing = true
74- let job
7591 if ( __DEV__ ) {
7692 seen = seen || new Map ( )
7793 }
@@ -87,15 +103,18 @@ function flushJobs(seen?: CountMap) {
87103 // during execution of another flushed job.
88104 queue . sort ( ( a , b ) => getId ( a ! ) - getId ( b ! ) )
89105
90- while ( ( job = queue . shift ( ) ) !== undefined ) {
91- if ( job === null ) {
92- continue
93- }
94- if ( __DEV__ ) {
95- checkRecursiveUpdates ( seen ! , job )
106+ for ( flushIndex = 0 ; flushIndex < queue . length ; flushIndex ++ ) {
107+ const job = queue [ flushIndex ]
108+ if ( job ) {
109+ if ( __DEV__ ) {
110+ checkRecursiveUpdates ( seen ! , job )
111+ }
112+ callWithErrorHandling ( job , null , ErrorCodes . SCHEDULER )
96113 }
97- callWithErrorHandling ( job , null , ErrorCodes . SCHEDULER )
98114 }
115+ flushIndex = 0
116+ queue . length = 0
117+
99118 flushPostFlushCbs ( seen )
100119 isFlushing = false
101120 // some postFlushCb queued jobs!
0 commit comments