想了解什么是宏任务和微任务,必须得知道 JavaScript 的执行顺序,JavaScript 是单线程,执行时存在各种任务队列。
常见的宏任务
业界流行的认为,可能个别浏览器有差异
类型
浏览器
Node
I/O
✅
✅
setTimeout
✅
✅
setInterval
✅
✅
setImmediate
❌
✅
requestAnimationFrame
✅
❌
常见的微任务
业界流行的认为,可能个别浏览器有差异
类型
浏览器
Node
process.nextTick
❌
✅
MutationObserver
✅
❌
Promise.then catch finally
✅
✅
在当前的微任务没有执行完成时,是不会执行下一个宏任务的
经典例子
setTimeout(_ => console.log(4))
new Promise(resolve => {
resolve()
console.log(1)
}).then(_ => {
console.log(3)
})
console.log(2)
经典提问:setTimeout 设置为 0 的作用
关键就是 setTimeout 是宏任务,不管延迟设置为多少还是会进入任务队列。
一些论证、讨论
https://www.cnblogs.com/xieex/archive/2008/07/11/1241137.html
http://www.cnblogs.com/silin6/p/4333999.html
使用宏任务和微任务知识完成:promise ES5 实现
function promise(fn) {
var value = null,
callbacks = []; //callbacks 为数组,因为可能同时有很多个回调
this.then = function (onFulfilled) {
callbacks.push(onFulfilled);
return this;
};
function resolve(value) {
setTimeout(function () {
callbacks.forEach(function (callback) {
callback(value);
});
}, 0)
}
fn(resolve);
}
function test() {
return new promise(function(resolve) {
console.log(‘1’);
resolve();
})
}
test().then(function(resolve) {
console.log(‘2’);
}).then(function(resolve) {
console.log(‘3’);
});