题目一
async function test1() {
console.log('test1 start')
await test2()
console.log('test2 end')
await test3()
console.log('test3 end')
}
async function test2() {
console.log('test2 start')
}
async function test3() {
console.log('test3 start')
}
console.log('script start')
test1()
console.log('script end')
考察内容:async await的执行顺序
理解:
1. 执行async函数,返回的是Promise对象;await 相当于Promise的then方法
2. promise初始化函数会立即执行,相当于同步;而promise.then相当于异步
就如同这个代码
async function test1() {
console.log('test1 start')
await test2()
console.log('test2 end')
}
async function test2() {
console.log('test2 start')
}
test1()
等同于下面这个
new Promise((resolve,reject) => {
console.log('test1 start')
new Promise((resolve,reject) => {
console.log('test2 start')
})
resolve()
}).then(() => {
console.log('test2 end')
})
根据以上理解,可以简单的得出代码的执行顺序了
先同步,后异步。从上往下,依次执行
同步代码
console.log('script start')
console.log('test1 start')
console.log('test2 start')
console.log('script end')
异步代码
console.log('test2 end')
console.log('test3 start')
console.log('test3 end')
题目二
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()
// 初始化promise时,传入的函数会被立刻执行
new Promise (function (resolve) {
console.log('promise1')
resolve()
}).then (function () {
console.log('promise2')
})
console.log('script end')
考察内容:
1. 同步和异步的执行顺序
2. promise初始化和promise.then的执行顺序
3. setTimeout和promise的执行顺序
4. async await 和promise的关系
回想一下,这些问题都了如指掌的话,那么这个题目也就非常简单了。
理解:
1. 同步先执行完成,再执行异步
2. promise初始化函数会立即执行,相当于同步。而promise.then相当于异步
3. setTimeout是宏任务,promise是微任务,微任务先于宏任务执行
4. 执行async函数,返回的是Promise对象;await 相当于Promise的then方法;try..catch 用来捕获异常,替代了Promise的catch
根据以上理解,从上往下执行过程中,会执行那些同步代码?异步代码又是哪些?
先执行的同步代码有
console.log('script start')
async1函数中的 console.log('async1 start')
async2函数中的 console.log('async2')
new Promise中的 console.log('promise1')
console.log('script end')
等同步代码执行完成后,再执行异步代码。从上往下,先微任务,后宏任务
async1函数中的 console.log('async1 end')
new Promise中的 console.log('promise2')
setTimeout中的 console.log('setTimeout')
题目三
Promise.resolve().then(() => {
console.log(0)
return Promise.resolve(4)
}).then((res) => {
console.log(res)
})
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
}).then(() => {
console.log(5)
}).then(() => {
console.log(6)
})
考察内容:promise.then执行问题
理解:
1. then交替执行
1. 如果有多个fulfilled promise 实例,同时执行then链式调用
2. then会交替执行
3. 这是编辑器的优化,防止一个promise占据太久时间
2. then中返回的新的promise实例
1. 也会遵循then交替执行
2. 但会出现“慢两拍”效果
3. 第一拍,新的promise需要由pending变为fulfilled,此时另一条链会执行一次then方法
4. 第二拍,新的promise的then方法挂载到MicroTaskQueue中,此时另一条链会再执行一次then方法
证实:
1, then交替执行
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(3)
})
Promise.resolve().then(() => {
console.log(2)
}).then(() => {
console.log(4)
})
从上往下,依次交替执行,输出结果是: 1 2 3 4
2. then中返回的新的promise实例
Promise.resolve().then(() => {
console.log(10);
return Promise.resolve(20)
}).then((res) => {
console.log(res)
}).then(() => {
console.log(30)
}).then(() => {
console.log(40)
}).then(() => {
console.log(50)
})
Promise.resolve().then(() => {
console.log(1)
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
}).then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
根据第一步证实的then交替执行,应该会出现这样的输出结果: 10 1 20 2 30 3 40 4 50 5
但是then中返回新的promise会慢两拍,因此实际输出的结果: 10 1 2 3 20 4 30 5 40 50
可以看出20的位置从第三位变成了第五位,比预想的慢了两拍
根据以上理解,可以简单的得出题目中代码的执行顺序了
第一次交替
1. 微任务队列:() => console.log(0)、() => console.log(1)
2. 执行打印:0 1
第二次交替
1. 微任务队列: Promise.resolve(4)【pendding => resolve】、() => console.log(2)
2. 执行打印:2
第三次交替
1. 微任务队列:Promise.resolve(4)【will add to microTaskQueue】、() => console.log(3)
2. 执行打印:3
第四次交替
1. 微任务队列:(res) => console.log(res)、() => console.log(5)
2. 执行打印:4 5
第五次交替
1. 微任务队列:() => console.log(6)
2. 执行打印:6
总结
-
async/await 和 Promise 的关系
- 执行async函数,返回的是Promise对象
- await 相当于Promise的then方法
- try..catch 用来捕获异常,替代了Promise的catch
-
宏任务和微任务
-
宏任务: setTimeout,setInterval, Ajax, DOM事件,setImmediate,I/O(Node.js)
-
微任务: Promise.then,MutaionObserve,process.nextTick,async/await
-
注意: 定时器的时间是指从执行定时器开始计时的,当时间到了之后就会把这个任务放到Callback Queue中
-
二者的执行时间:微任务 --》 DOM渲染 --》 宏任务
-
执行顺序是:
- Call Stack清空
- 执行当前的微任务
- 尝试渲染DOM
- 触发event loop机制
-
-
promise.then执行问题
-
then交替执行
- 如果有多个fulfilled promise 实例,同时执行then链式调用
- then会交替执行
- 这是编辑器的优化,防止一个promise占据太久时间
-
then中返回新的promise实例
- 也会遵循交替执行
- 但会出现“慢两拍”的效果
- 第一拍,promise需要由pending变为fulfilled
- 第二拍,then函数挂载到MicroTaskQueue中去
-