想了解什么是宏任务和微任务,必须得知道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');
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。