前言
先看一段代码
setTimeout(function() {
console.log(‘timeout’);
}, 0);
new Promise((resolve, reject) => {
console.log(‘promise’);
resolve();
}).then(function() {
console.log(‘then’);
});
console.log(‘global’);
输出:promise、global、then、timeout
macrotasks 和 microtasks
在 V8 实现中包含两种任务:
macrotasks
script ,setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks
process.nextTick, Promises, Object.observe, MutationObserver
执行过程如下:
JavaScript 引擎首先从 macrotask queue 中取出第一个任务,
执行完毕后,将 microtask queue 中的所有任务取出,按顺序全部执行;
浏览器进行渲染视图然后再从 macrotask queue 中取下一个,
执行完毕后,再次将 microtask queue 中的全部取出;
循环往复,直到两个 queue 中的任务都取完。
注意:
从上面可以看到,microtask 会执行完毕才进行渲染,如果 microtask 执行时间教长,会导致卡顿
上面执行过程只是 chrome 的,safri 又不太一样
执行过程的示例:https://jakearchibald.com/201…
如何模拟 Promise.then
new MutationObserver(function() {
console.log(‘mutate’);
}).observe(document.body, {
attributes: true
});
document.body.setAttribute(‘data-random’, Math.random());
setTimeout(function() {
console.log(‘timeout’);
}, 0);
new Promise((resolve, reject) => {
console.log(‘promise’);
resolve();
}).then(function() {
console.log(‘then’);
});
console.log(‘global’);
输出:promise、global、mutate、then、timeout
参考文章:
microTask: https://github.com/kaerus-com…
es-promise : https://github.com/stefanpenn…