@@ -8,13 +8,7 @@ import {
8
8
devtools
9
9
} from '../util/index'
10
10
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
-
16
11
const queue : Array < Watcher > = []
17
- const userQueue: Array< Watcher > = []
18
12
let has: { [ key : number ] : ?true } = { }
19
13
let circular: { [ key : number ] : number } = { }
20
14
let waiting = false
@@ -26,7 +20,6 @@ let index = 0
26
20
*/
27
21
function resetSchedulerState () {
28
22
queue . length = 0
29
- userQueue . length = 0
30
23
has = { }
31
24
if ( process . env . NODE_ENV !== 'production' ) {
32
25
circular = { }
@@ -39,31 +32,17 @@ function resetSchedulerState () {
39
32
*/
40
33
function flushSchedulerQueue ( ) {
41
34
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
- }
51
35
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 )
62
45
63
- /**
64
- * Run the watchers in a single queue.
65
- */
66
- function runSchedulerQueue (queue: Array< Watcher > ) {
67
46
// do not cache length because more watchers might be pushed
68
47
// as we run existing watchers
69
48
for ( index = 0 ; index < queue . length ; index ++ ) {
@@ -87,7 +66,14 @@ function runSchedulerQueue (queue: Array<Watcher>) {
87
66
}
88
67
}
89
68
}
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 ( )
91
77
}
92
78
93
79
/**
@@ -98,24 +84,17 @@ function runSchedulerQueue (queue: Array<Watcher>) {
98
84
export function queueWatcher ( watcher : Watcher ) {
99
85
const id = watcher . id
100
86
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
107
87
has [ id ] = true
108
- const q = watcher . user
109
- ? userQueue
110
- : queue
111
88
if ( ! flushing ) {
112
- q . push ( watcher )
89
+ queue . push ( watcher )
113
90
} 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 ) {
116
95
i --
117
96
}
118
- q . splice ( Math . max ( i , index ) + 1 , 0 , watcher )
97
+ queue . splice ( Math . max ( i , index ) + 1 , 0 , watcher )
119
98
}
120
99
// queue the flush
121
100
if ( ! waiting ) {
0 commit comments