8000 ensure newly pushed watchers are run after current one is done (fix #… · ctyu/vue@b781ab0 · GitHub
[go: up one dir, main page]

Skip to content

Commit b781ab0

Browse files
committed
ensure newly pushed watchers are run after current one is done (fix vuejs#2424)
1 parent 4b68876 commit b781ab0

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

src/batcher.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
// before user watchers so that when user watchers are
1212
// triggered, the DOM would have already been in updated
1313
// state.
14+
15+
var queueIndex
1416
var queue = []
1517
var userQueue = []
1618
var has = {}
@@ -55,8 +57,8 @@ function flushBatcherQueue () {
5557
function runBatcherQueue (queue) {
5658
// do not cache length because more watchers might be pushed
5759
// as we run existing watchers
58-
for (var i = 0; i < queue.length; i++) {
59-
var watcher = queue[i]
60+
for (queueIndex = 0; queueIndex < queue.length; queueIndex++) {
61+
var watcher = queue[queueIndex]
6062
var id = watcher.id
6163
has[id] = null
6264
watcher.run()
@@ -88,20 +90,22 @@ function runBatcherQueue (queue) {
8890
export function pushWatcher (watcher) {
8991
var id = watcher.id
9092
if (has[id] == null) {
91-
// if an internal watcher is pushed, but the internal
92-
// queue is already depleted, we run it immediately.
9393
if (internalQueueDepleted && !watcher.user) {
94-
watcher.run()
95-
return
96-
}
97-
// push watcher into appropriate queue
98-
var q = watcher.user ? userQueue : queue
99-
has[id] = q.length
100-
q.push(watcher)
101-
// queue the flush
102-
if (!waiting) {
103-
waiting = true
104-
nextTick(flushBatcherQueue)
94+
// an internal watcher triggered by a user watcher...
95+
// let's run it immediately after current user watcher is done.
96+
userQueue.splice(queueIndex + 1, 0, watcher)
97+
} else {
98+
// push watcher into appropriate queue
99+
var q = watcher.user
100+
? userQueue
101+
: queue
102+
has[id] = q.length
103+
q.push(watcher)
104+
// queue the flush
105+
if (!waiting) {
106+
waiting = true
107+
nextTick(flushBatcherQueue)
108+
}
105109
}
106110
}
107111
}

test/unit/specs/batcher_spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,26 @@ describe('Batcher', function () {
9797
done()
9898
})
9999
})
100+
101+
it('should call newly pushed watcher after current watcher is done', function (done) {
102+
var callOrder = []
103+
batcher.pushWatcher({
104+
id: 1,
105+
user: true,
106+
run: function () {
107+
callOrder.push(1)
108+
batcher.pushWatcher({
109+
id: 2,
110+
run: function () {
111+
callOrder.push(3)
112+
}
113+
})
114+
callOrder.push(2)
115+
}
116+
})
117+
nextTick(function () {
118+
expect(callOrder.join()).toBe('1,2,3')
119+
done()
120+
})
121+
})
100122
})

0 commit comments

Comments
 (0)
0