图片授权基于 CC0 协议
JavaScript 的引擎常驻于内存当中,我们把 JavaScript 代码传递给 JavaScript 引擎,引擎就会执行代码。
在 ES5 后 JavaScript 引入了 Promise ,然后呢 JavaScript 引擎本身也可以发起任务了。
JavaScript 执行任务分为「宏任务」和「微任务」,任务不同执行顺序也就不同。我们简单分析一下「不同任务类型」执行状况。
Promise 微任务
console.log(\\\'console.log1\\\');
Promise.resolve().then(()=>{
console.log(\\\'Promise\\\');
})
console.log(\\\'console.log2\\\');
//先输出 console.log1
//再输出 console.log2
//最后输出 Promise
JavaScript 是从上到下执行,先执行到 Promise 会生成一个微任务,添加到「当前宏任务」的最后面执行。微任务也是有队列的,微任务执行完后,才会执行下一个宏任务。
setTimeout 宏任务
console.log(\\\'console.log1\\\');
setTimeout(()=>{
console.log(\\\'setTimeout\\\')
},0)
console.log(\\\'console.log2\\\');
//先输出 console.log1
//再输出 console.log2
//最后输出 Promise
执行顺序和 Promise 一样。不同的是 setTimeout 属于宏任务。执行完当前宏任务后,执行 setTimeout 时会添加到宏任务列表。
等待上一个宏任务执行完后,会在宏任务队列里取出下一个宏任务来执行。
那当 Promise(微任务) 和 setTimeout(宏任务) 一起执行的时候,会发生什么?
console.log(\\\'console.log1\\\');
setTimeout(()=>{
console.log(\\\'setTimeout\\\')
},0)
Promise.resolve().then(()=>{
console.log(\\\'Promise\\\');
})
console.log(\\\'console.log2\\\');
//console.log1
//console.log2
//Promise
//setTimeout
上面的代码都属于一个宏任务。console.log1 直接输出;setTimeout 添加到宏任务的队列;其次执行 Promise 添加到当前宏任务的最后执行;再然后执行 console.log2 ;
当前宏任务执行完后,会查找宏任务里是否还有微任务,有就执行微任务队列,没有就执行下一个宏任务;
微任务执行完后,再去寻找下一个宏任务。
Promise 永远在队列尾部添加微任务。setTimeout 等宿主 API 则会添加宏任务。Promise 产生的是 JavaScript 引擎内部的微任务,而 setTimeout 是浏览器 API,它产生宏任务。
async/await 新特性
function sleep(duration) {
return new Promise(function(resolve,reject) {
console.log(\\\'await\\\');
Promise.resolve().then(()=>{
console.log(\\\'await-promise\\\');
})
setTimeout(resolve,duration)
})
}
async function foo(){
await sleep(2000)
console.log(\\\'2秒后输出\\\')
}
foo();
//await
//await-promise
//2秒后输出
在 function 函数前面加上 async 关键字,就定义了一个 async 函数。
await 后面一般跟的是 Promise ,我自己的理解是 await 在当前宏任务中去执行一个微任务。微任务里有宏任务,那微任务也要执行完,才可以向后继续执行。
参考资料:
[1]极客时间《重学前端》
[2]https://segmentfault.com/a/1190000011198232
[3]https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
[4]https://juejin.im/post/5b498d245188251b193d405
推荐一门课程:
原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34582.html