@@ -8,13 +8,7 @@ import {
88 devtools
99} from '../util/index'
1010
11- // We have two separate queues: one for internal component re-render updates
12- // and one for user watcher registered via $watch(). We want to guarantee
13- // re-render updates to be called before user watchers so that when user
14- // watchers are triggered, the DOM would already be in updated state.
15-
1611const queue : Array < Watcher > = []
17- const userQueue: Array< Watcher > = []
1812let has: { [ key : number ] : ?true } = { }
1913let circular: { [ key : number ] : number } = { }
2014let waiting = false
@@ -26,7 +20,6 @@ let index = 0
2620 */
2721function resetSchedulerState () {
2822 queue . length = 0
29- userQueue . length = 0
3023 has = { }
3124 if ( process . env . NODE_ENV !== 'production' ) {
3225 circular = { }
@@ -39,31 +32,17 @@ function resetSchedulerState () {
3932 */
4033function flushSchedulerQueue ( ) {
4134 flushing = true
42- runSchedulerQueue ( userQueue )
43- runSchedulerQueue ( queue . sort ( queueSorter ) )
44- // devtool hook
45- /* istanbul ignore if */
46- if ( devtools && config . devtools ) {
47- devtools . emit ( 'flush' )
48- }
49- resetSchedulerState()
50- }
5135
52- /**
53- * Sort queue before flush.
54- * This ensures components are updated from parent to child
55- * so there will be no duplicate updates, e.g. a child was
56- * pushed into the queue first and then its parent's props
57- * changed.
58- */
59- function queueSorter ( a : Watcher , b : Watcher ) {
60- return a . id - b . id
61- }
36+ // Sort queue before flush.
37+ // This ensures that:
38+ // 1. Components are updated from parent to child. (because parent is always
39+ // created before the child)
40+ // 2. A component's user watchers are run before its render watcher (because
41+ // user watchers are created before the render watcher)
42+ // 3. If a component is destroyed during a parent component's watcher run,
43+ // its watchers can be skipped.
44+ queue . sort ( ( a , b ) => a . id - b . id )
6245
63- /**
64- * Run the watchers in a single queue.
65- */
66- function runSchedulerQueue (queue: Array< Watcher > ) {
6746 // do not cache length because more watchers might be pushed
6847 // as we run existing watchers
6948 for ( index = 0 ; index < queue . length ; index ++ ) {
@@ -87,7 +66,14 @@ function runSchedulerQueue (queue: Array<Watcher>) {
8766 }
8867 }
8968 }
90- queue . length = 0
69+
70+ // devtool hook
71+ /* istanbul ignore if */
72+ if ( devtools && config . devtools ) {
73+ devtools . emit ( 'flush' )
74+ }
75+
76+ resetSchedulerState ( )
9177}
9278
9379/**
@@ -98,24 +84,17 @@ function runSchedulerQueue (queue: Array<Watcher>) {
9884export function queueWatcher ( watcher : Watcher ) {
9985 const id = watcher . id
10086 if ( has [ id ] == null ) {
101- // if already flushing, and all user watchers have already been run,
102- // run the new user watcher immediately.
103- if ( flushing && watcher . user && ! userQueue . length ) {
104- return watcher . run ( )
105- }
106- // push watcher into appropriate queue
10787 has [ id ] = true
108- const q = watcher . user
109- ? userQueue
110- : queue
11188 if ( ! flushing ) {
112- q . push ( watcher )
89+ queue . push ( watcher )
11390 } else {
114- let i = q . length - 1
115- while ( i >= 0 && q [ i ] . id > watcher . id ) {
91+ // if already flushing, splice the watcher based on its id
92+ // if already past its id, it will be run next immediately.
93+ let i = queue . length - 1
94+ while ( i >= 0 && queue [ i ] . id > watcher . id ) {
11695 i --
11796 }
118- q . splice ( Math . max ( i , index ) + 1 , 0 , watcher )
97+ queue . splice ( Math . max ( i , index ) + 1 , 0 , watcher )
11998 }
12099 // queue the flush
121100 if ( ! waiting ) {
0 commit comments