@@ -5,6 +5,7 @@ import { warn } from './warning'
55
66export interface SchedulerJob extends Function {
77 id ?: number
8+ pre ?: boolean
89 active ?: boolean
910 computed ?: boolean
1011 /**
@@ -39,19 +40,13 @@ let isFlushPending = false
3940const queue : SchedulerJob [ ] = [ ]
4041let flushIndex = 0
4142
42- const pendingPreFlushCbs : SchedulerJob [ ] = [ ]
43- let activePreFlushCbs : SchedulerJob [ ] | null = null
44- let preFlushIndex = 0
45-
4643const pendingPostFlushCbs : SchedulerJob [ ] = [ ]
4744let activePostFlushCbs : SchedulerJob [ ] | null = null
4845let postFlushIndex = 0
4946
5047const resolvedPromise = /*#__PURE__*/ Promise . resolve ( ) as Promise < any >
5148let currentFlushPromise : Promise < void > | null = null
5249
53- let currentPreFlushParentJob : SchedulerJob | null = null
54-
5550const RECURSION_LIMIT = 100
5651type CountMap = Map < SchedulerJob , number >
5752
@@ -89,12 +84,11 @@ export function queueJob(job: SchedulerJob) {
8984 // allow it recursively trigger itself - it is the user's responsibility to
9085 // ensure it doesn't end up in an infinite loop.
9186 if (
92- ( ! queue . length ||
93- ! queue . includes (
94- job ,
95- isFlushing && job . allowRecurse ? flushIndex + 1 : flushIndex
96- ) ) &&
97- job !== currentPreFlushParentJob
87+ ! queue . length ||
88+ ! queue . includes (
89+ job ,
90+ isFlushing && job . allowRecurse ? flushIndex + 1 : flushIndex
91+ )
9892 ) {
9993 if ( job . id == null ) {
10094 queue . push ( job )
@@ -119,71 +113,44 @@ export function invalidateJob(job: SchedulerJob) {
119113 }
120114}
121115
122- function queueCb (
123- cb : SchedulerJobs ,
124- activeQueue : SchedulerJob [ ] | null ,
125- pendingQueue : SchedulerJob [ ] ,
126- index : number
127- ) {
116+ export function queuePostFlushCb ( cb : SchedulerJobs ) {
128117 if ( ! isArray ( cb ) ) {
129118 if (
130- ! activeQueue ||
131- ! activeQueue . includes ( cb , cb . allowRecurse ? index + 1 : index )
119+ ! activePostFlushCbs ||
120+ ! activePostFlushCbs . includes (
121+ cb ,
122+ cb . allowRecurse ? postFlushIndex + 1 : postFlushIndex
123+ )
132124 ) {
133- pendingQueue . push ( cb )
125+ pendingPostFlushCbs . push ( cb )
134126 }
135127 } else {
136128 // if cb is an array, it is a component lifecycle hook which can only be
137129 // triggered by a job, which is already deduped in the main queue, so
138130 // we can skip duplicate check here to improve perf
139- pendingQueue . push ( ...cb )
131+ pendingPostFlushCbs . push ( ...cb )
140132 }
141133 queueFlush ( )
142134}
143135
144- export function queuePreFlushCb ( cb : SchedulerJob ) {
145- queueCb ( cb , activePreFlushCbs , pendingPreFlushCbs , preFlushIndex )
146- }
147-
148- export function queuePostFlushCb ( cb : SchedulerJobs ) {
149- queueCb ( cb , activePostFlushCbs , pendingPostFlushCbs , postFlushIndex )
150- }
151-
152- export function flushPreFlushCbs (
153- seen ?: CountMap ,
154- parentJob : SchedulerJob | null = null
155- ) {
156- if ( pendingPreFlushCbs . length ) {
157- currentPreFlushParentJob = parentJob
158- activePreFlushCbs = [ ...new Set ( pendingPreFlushCbs ) ]
159- pendingPreFlushCbs . length = 0
160- if ( __DEV__ ) {
161- seen = seen || new Map ( )
162- }
163- for (
164- preFlushIndex = 0 ;
165- preFlushIndex < activePreFlushCbs . length ;
166- preFlushIndex ++
167- ) {
168- if (
169- __DEV__ &&
170- checkRecursiveUpdates ( seen ! , activePreFlushCbs [ preFlushIndex ] )
171- ) {
136+ export function flushPreFlushCbs ( seen ?: CountMap , i = flushIndex ) {
137+ if ( __DEV__ ) {
138+ seen = seen || new Map ( )
139+ }
140+ for ( ; i < queue . length ; i ++ ) {
141+ const cb = queue [ i ]
142+ if ( cb && cb . pre ) {
143+ if ( __DEV__ && checkRecursiveUpdates ( seen ! , cb ) ) {
172144 continue
173145 }
174- activePreFlushCbs [ preFlushIndex ] ( )
146+ queue . splice ( i , 1 )
147+ i --
148+ cb ( )
175149 }
176- activePreFlushCbs = null
177- preFlushIndex = 0
178- currentPreFlushParentJob = null
179- // recursively flush until it drains
180- flushPreFlushCbs ( seen , parentJob )
181150 }
182151}
183152
184153export function flushPostFlushCbs ( seen ?: CountMap ) {
185- // flush any pre cbs queued during the flush (e.g. pre watchers)
186- flushPreFlushCbs ( )
187154 if ( pendingPostFlushCbs . length ) {
188155 const deduped = [ ...new Set ( pendingPostFlushCbs ) ]
189156 pendingPostFlushCbs . length = 0
@@ -222,23 +189,30 @@ export function flushPostFlushCbs(seen?: CountMap) {
222189const getId = ( job : SchedulerJob ) : number =>
223190 job . id == null ? Infinity : job . id
224191
192+ const comparator = ( a : SchedulerJob , b : SchedulerJob ) : number => {
193+ const diff = getId ( a ) - getId ( b )
194+ if ( diff === 0 ) {
195+ if ( a . pre && ! b . pre ) return - 1
196+ if ( b . pre && ! a . pre ) return 1
197+ }
198+ return diff
199+ }
200+
225201function flushJobs ( seen ?: CountMap ) {
226202 isFlushPending = false
227203 isFlushing = true
228204 if ( __DEV__ ) {
229205 seen = seen || new Map ( )
230206 }
231207
232- flushPreFlushCbs ( seen )
233-
234208 // Sort queue before flush.
235209 // This ensures that:
236210 // 1. Components are updated from parent to child. (because parent is always
237211 // created before the child so its render effect will have smaller
238212 // priority number)
239213 // 2. If a component is unmounted during a parent component's update,
240214 // its update can be skipped.
241- queue . sort ( ( a , b ) => getId ( a ) - getId ( b ) )
215+ queue . sort ( comparator )
242216
243217 // conditional usage of checkRecursiveUpdate must be determined out of
244218 // try ... catch block since Rollup by default de-optimizes treeshaking
@@ -270,11 +244,7 @@ function flushJobs(seen?: CountMap) {
270244 currentFlushPromise = null
271245 // some postFlushCb queued jobs!
272246 // keep flushing until it drains.
273- if (
274- queue . length ||
275- pendingPreFlushCbs . length ||
276- pendingPostFlushCbs . length
277- ) {
247+ if ( queue . length || pendingPostFlushCbs . length ) {
278248 flushJobs ( seen )
279249 }
280250 }
0 commit comments