知识前置:微任务(microtask),宏任务(macrotask),async和await是promise的语法糖。
Promise虽然是异步函数,但并不是全部是异步函数,只有then之后的部分才是异步函数,then之前的是同步函数。
案例1
async await函数转换成Promise函数
如果async函数里没有使用await函数,那么async函数就等于普通的function函数。
// 业务1 async await 写法
async function async1() {
console.log("A");
await async2()
console.log("B");
}
async function async2() {
console.log("C");
}
console.log("D");
// 业务1 转换成pomise 写法
async function async1() {
console.log("A");
new Promise((resolve) => {
console.log("C"); // 同步代码
resolve()
}).then(res => console.log("B")) //异步代码
}
console.log("D");
// 输出结果一样 D A C B
案例2
先微后宏原则
宏任务(macro-task):
主线程代码(script中的代码),setTimeout,setInterval,setImmediate,requestAnimationFrame,I/O流,UI render(UI页面渲染),ajax请求微任务(micro-task):
process.nextTick(node v8机制引擎里有个专门的宏任务去解析)
Promise(准确的说是new Promise().then())
Async/Await(实际就是promise)
MutationObserver(html5新特性)执行流程
先执行宏任务(特指js主线程)- 执行完毕
先询问是否有可执行的微任务,如果没有再去执行宏任务,如果有微任务,先执行微任务再执行宏任务如果宏任务嵌套微任务,微任务嵌套宏任务
先执行第一个层面的微任务队列,执行完毕才会执行第二个队列的宏任务。
可以用作用域嵌套来理解。最后整个执行的两个原则:
先同后异
先微后宏
async function async1() {
console.log("A");
await async2()
console.log("B");
}
async function async2() {
console.log("C");
}
console.log("D");
setTimeout(function () {
console.log("E");
}, 0)
async1()
new Promise(function (resolve) {
console.log("F");
resolve()
}).then(function () {
console.log("G");
})
console.log("H");
/** 输出结果
* D A C F H B G E
*
* */