nextTick
/**
*
* @params {function} cb 执行回调函数
* @params ctx 作用域
*/
function nextTick (cb, ctx) {
// 私有变量,用于存储 Promise 中的 resolve 函数
var _resolve;
// callbacks 用于存储待执行的 callback
callbacks.push(function () {
if (cb) {
cb.call(ctx);
}
else if (_resolve) {
_resolve(ctx);
}
});
// 异步锁,保证只执行一次延时函数
if (!pending) {
pending = true;
// 微型定时函数,用于执行 callbacks 中的函数
microTimerFunc();
// callbacks.forEach(fn => Promise.resolve().then(fn))
}
if (!cb) {
return new Promise(function (resolve) {
_resolve = resolve;
})
}
}
复制代码
关于 pending 异步锁的讲解可以参考 juejin.im/post/5c0350…
microTimerFunc
采用了如下的降级策略:
- Micro Task
- 2.0 rc6 用的 MutationObserver (IOS 9.3)
- 2.0 rc7 用的 postMessage
- 现在用的是原生 Promise
- Macro Task
- setImmediate
- MessageChannel
- setTimeout
也就是说 this.nexTtick(fn)中的 fn 能够保证在当前 Event Loop 末尾,能够获取到最新的 DOM 树。