Skip to content

Commit 472b897

Browse files
committed
adjust scheduler: call user watchers before component updates
1 parent 27c221b commit 472b897

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

src/core/observer/scheduler.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,8 @@ function resetSchedulerState () {
3939
*/
4040
function flushSchedulerQueue () {
4141
flushing = true
42-
runSchedulerQueue(queue.sort(queueSorter))
4342
runSchedulerQueue(userQueue)
44-
// user watchers triggered more watchers,
45-
// keep flushing until it depletes
46-
if (queue.length) {
47-
return flushSchedulerQueue()
48-
}
43+
runSchedulerQueue(queue.sort(queueSorter))
4944
// devtool hook
5045
/* istanbul ignore if */
5146
if (devtools && config.devtools) {
@@ -103,11 +98,16 @@ function runSchedulerQueue (queue: Array<Watcher>) {
10398
export function queueWatcher (watcher: Watcher) {
10499
const id = watcher.id
105100
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+
}
106106
// push watcher into appropriate queue
107+
has[id] = true
107108
const q = watcher.user
108109
? userQueue
109110
: queue
110-
has[id] = true
111111
if (!flushing) {
112112
q.push(watcher)
113113
} else {

test/unit/modules/observer/scheduler.spec.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('Scheduler', () => {
4545
}).then(done)
4646
})
4747

48-
it('calls user watchers after directive updates', done => {
48+
it('call user watchers before component re-render', done => {
4949
const vals = []
5050
function run () {
5151
vals.push(this.id)
@@ -67,9 +67,34 @@ describe('Scheduler', () => {
6767
run: run
6868
})
6969
waitForUpdate(() => {
70-
expect(vals[0]).toBe(1)
71-
expect(vals[1]).toBe(2)
72-
expect(vals[2]).toBe(3)
70+
expect(vals).toEqual([2, 1, 3])
71+
}).then(done)
72+
})
73+
74+
it('call user watcher triggered by component re-render immediately', done => {
75+
// this happens when a component re-render updates the props of a child
76+
const vals = []
77+
queueWatcher({
78+
id: 1,
79+
run () {
80+
vals.push(1)
81+
queueWatcher({
82+
id: 3,
83+
user: true,
84+
run () {
85+
vals.push(3)
86+
}
87+
})
88+
}
89+
})
90+
queueWatcher({
91+
id: 2,
92+
run () {
93+
vals.push(2)
94+
}
95+
})
96+
waitForUpdate(() => {
97+
expect(vals).toEqual([1, 3, 2])
7398
}).then(done)
7499
})
75100

@@ -106,7 +131,7 @@ describe('Scheduler', () => {
106131
}
107132
})
108133
waitForUpdate(() => {
109-
expect(callOrder.join()).toBe('1,2,3')
134+
expect(callOrder).toEqual([1, 2, 3])
110135
}).then(done)
111136
})
112137
})

0 commit comments

Comments
 (0)