异步任务的执行,是有一个优先级的顺序的,包括了 宏任务(macrotasks) 和 微任务(microtasks)
宏任务:整体代码script setTimeout, setInterval, setImmediate, I/O, UI rendering
微任务: Promises.(then catch finally), process.nextTick, MutationObserver
宏任务和微任务的区别在于在事件循环机制中,执行的机制不同
排在前面的script最先执行,然后再执行同步任务与微任务,接着执行下一个宏任务。 我们在工作常用到的宏任务是 setTimeout ,而微任务是 Promise.then
自己的理解:js是单线程,执行机制简单来说就是先同步后异步,setTimeout是放在宏任务里面,最后执行,await必须放在async里面执行,是同步任务,然后async会返回一个promise,promise是同步,.then是异步任务
注意这里是Promise.then,也就是说 new Promise在实例化 的过程中所执行的代码是同步的,而在 then 中注册的回调函数才是异步。
注意:放进去宏任务和微任务都遵循先进先出的执行机制
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');
resolve();
}).then(function () {
console.log('promise2');
})
console.log('script end');
执行顺序:
1、执行console.log('script start'),输出script start;
2、执行setTimeout,是一个异步动作,放入宏任务异步队列中;
3、执行async1(),输出async1 start,继续向下执行;
4、执行async2(),输出async2,并返回了一个promise对象,await让出了线程,把返回的promise加入了微任务异步队列,所以async1()下面的代码也要等待上面完成后继续执行;
5、执行 new Promise,输出promise1,然后将resolve放入微任务异步队列;
6、执行console.log('script end'),输出script end;
7、到此同步的代码就都执行完成了,然后去微任务异步队列里去获取任务
8、接下来执行resolve(async2返回的promise返回的),输出了async1 end。
9、然后执行resolve(new Promise的),输出了promise2。
10、最后执行setTimeout,输出了settimeout。