先看题:
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve()
}).then(function() {
console.log('promise2');
})
console.log('script end');
怎么样,晕不晕?来一个个了解下涉及知识点:
- async函数是使用async关键字声明的函数,且其中允许使用await关键字,async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步操作,无需链式调用Promise。
- async函数一定会返回一个promise对象
- 一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行
- 所以 async 函数的第一行将会同步执行,await将会等待promise的结束。然后暂停 async1 的进程,并将控制权交还给调用 async1 的函数。
- 一段时间后,当第一个promise完结的时候,下面的promise1 和 script end 已同步打印完成,这时候promise状态为fulfilled,打印async1 end, 下面是异步的promise2.
- 最后就是为啥setTimeout最后执行,因为setTimeout不仅是异步还是宏任务,和promise进入不同的事件对接
macro-task(宏任务):包括整体代码script,setTimeout,setInterva
micro-task(微任务):Promise,process.nextTi
不同的任务会进入到不同的event queue
graph TD
A[宏任务] --> B[执行结束]
B --> C{有可执行的微任务吗}
C --> |没有| A[宏任务]
C --> |有| D[执行所有微任务]
D --> A[宏任务]
事件循环,宏任务,微任务的关系图
所以现在遍豁然开朗了,遇到setTimeout,将其放到宏任务event queue里面,回到 promise , new promise 会立即执行, then会分发到微任务,整体宏任务执行完成,接下来判断是否有微任务,async1里的await有一个promise对象,所以async1 end 及 promise2微任务执行,微任务执行完,开始执行异步宏任务setTimeout.
所以上面题的执行结果是: script start async1 start async2 promise1 script end async1 end promise2 setTimeout 怎么样,是不是醍醐灌顶,哈哈哈