Skip to content

Commit c9b425d

Browse files
committed
improve nextTick
1 parent b5ac185 commit c9b425d

File tree

1 file changed

+35
-40
lines changed

1 file changed

+35
-40
lines changed

src/util/env.js

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,55 +20,50 @@ var inBrowser = exports.inBrowser =
2020
/**
2121
* Defer a task to execute it asynchronously. Ideally this
2222
* should be executed as a microtask, so we leverage
23-
* MutationObserver if it's available.
24-
*
25-
* If the user has included a setImmediate polyfill, we can
26-
* also use that. In Node we actually prefer setImmediate to
27-
* process.nextTick so we don't block the I/O.
28-
*
29-
* Finally, fallback to setTimeout(0) if nothing else works.
23+
* MutationObserver if it's available, and fallback to
24+
* setTimeout(0).
3025
*
3126
* @param {Function} cb
3227
* @param {Object} ctx
3328
*/
3429

35-
var defer
36-
/* istanbul ignore if */
37-
if (typeof MutationObserver !== 'undefined') {
38-
defer = deferFromMutationObserver(MutationObserver)
39-
} else
40-
/* istanbul ignore if */
41-
if (typeof WebkitMutationObserver !== 'undefined') {
42-
defer = deferFromMutationObserver(WebkitMutationObserver)
43-
} else {
44-
defer = setTimeout
45-
}
46-
47-
/* istanbul ignore next */
48-
function deferFromMutationObserver (Observer) {
49-
var queue = []
50-
var node = document.createTextNode('0')
51-
var i = 0
52-
new Observer(function () {
53-
var l = queue.length
54-
for (var i = 0; i < l; i++) {
55-
queue[i]()
30+
exports.nextTick = (function () {
31+
var callbacks = []
32+
var pending = false
33+
var timerFunc
34+
function handle () {
35+
pending = false
36+
var copies = callbacks.slice(0)
37+
callbacks = []
38+
for (var i = 0; i < copies.length; i++) {
39+
copies[i]()
5640
}
57-
queue = queue.slice(l)
58-
}).observe(node, { characterData: true })
59-
return function mutationObserverDefer (cb) {
60-
queue.push(cb)
61-
node.nodeValue = (i = ++i % 2)
6241
}
63-
}
64-
65-
exports.nextTick = function (cb, ctx) {
66-
if (ctx) {
67-
defer(function () { cb.call(ctx) }, 0)
42+
/* istanbul ignore if */
43+
if (typeof MutationObserver !== 'undefined') {
44+
var counter = 1
45+
var observer = new MutationObserver(handle)
46+
var textNode = document.createTextNode(counter)
47+
observer.observe(textNode, {
48+
characterData: true
49+
})
50+
timerFunc = function () {
51+
counter = (counter + 1) % 2
52+
textNode.data = counter
53+
}
6854
} else {
69-
defer(cb, 0)
55+
timerFunc = setTimeout
56+
}
57+
return function (cb, ctx) {
58+
var func = ctx
59+
? function () { cb.call(ctx) }
60+
: cb
61+
callbacks.push(func)
62+
if (pending) return
63+
pending = true
64+
timerFunc(handle, 0)
7065
}
71-
}
66+
})()
7267

7368
/**
7469
* Detect if we are in IE9...

0 commit comments

Comments
 (0)