javascript 是一种单线程语言,同一时刻只能运行一个线程
执行顺序:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕
即:同步任务->异步微任务->异步宏任务(由先到后)
| 宏任务(macrotask) | 微任务(microtask) | |
|---|---|---|
| 谁发起的 | 宿主(Node、浏览器) | JS引擎 |
| 具体事件 | 1. script (可以理解为外层同步代码) 2. setTimeout/setInterval 3. UI rendering/UI事件 4. postMessage,MessageChannel 5. setImmediate,I/O(Node.js) | 1. Promise 2. MutaionObserver 3. Object.observe(已废弃;Proxy 对象替代) 4. process.nextTick(Node.js) |
| 谁先运行 | 后运行 | 先运行 |
| 会触发新一轮Tick吗 | 会 | 不会 |
示例一:
async function async1() {
console.log('async1 start');
await async2();
console.log('asnyc1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(() => {
console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
console.log('promise1');
reslove();
}).then(function () {
console.log('promise2');
})
console.log('script end');
// 答案
1、script start
2、async1 start
3、async2
4、promise1
5、script end
6、asnyc1 end
7、promise2
8、setTimeOut
示例二:
setTimeout(function(){
console.log('1');
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3');
}).then(function(){
console.log('4')
});
console.log('5');
// 2 5 3 4 1
// 1.遇到setTimout,异步宏任务,放入宏任务队列中
// 2.遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2
// 3.而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
// 4.遇到同步任务console.log(‘5’);输出5;主线程中同步任务执行完
// 5.从微任务队列中取出任务到主线程中,输出3、 4,微任务队列为空
// 6.从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空
参考