想了解什麼是宏任務和微任務,必須得知道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');
});