我们都知道async-wait与generator的出现,是为了能让我们更好地去控制异步逻辑,避免回调函数的地狱

666.jpg

但是你确定真的完全掌握他俩的用法了吗?下面我会列出他们各自不同的用法,看下实际运行的结果与你的想法是否一致吧,废话不多说,开搞!

ppx2.jpg

async-await

首先我们先看下async-await的不同用法,你可以自己先思考下每个使用场景的输出,看下是否与最终结果一致

场景一

1
2
3
4
5
6
async function test() {
await console.log(1)
console.log(2)
}
test()
console.log(3)

程序运行过程如下:

  1. 执行test函数,遇见 await,执行后面的语句,打印出1,并让出执行权
  2. 执行test函数后面的console.log(3),打印出3
  3. 返回test函数,执行await后面的console.log(2),打印出2

所以最终输出为 1,3,2

场景二

1
2
3
4
5
6
7
8
async function test() {
await setTimeout(()=>{
console.log(1)
},0)
console.log(2)
}
test()
console.log(3)

程序运行过程如下:

  1. 执行test函数,遇见 await,执行后面的语句,将 setTimeout 的回调放入 宏任务队列
  2. 执行test函数后面的console.log(3),打印出3
  3. 返回test函数,执行await后面的console.log(2),打印出2
  4. 执行宏任务队列里的回调,打印出1

所以最终输出为 3,2,1,从这个例子我们可以看出await后面语句的优先级是高于宏任务的

场景三

1
2
3
4
5
6
7
8
async function test() {
await Promise.resolve(1).then(res=>{
console.log(res)
})
console.log(2)
}
test()
console.log(3)

程序运行过程如下:

  1. 执行test函数,遇见 await,执行后面的语句,将 Promise 的回调放入 微任务队列
  2. 执行test函数后面的console.log(3),打印出3
  3. 执行微任务队列里的任务,打印出1
  4. 返回test函数,执行await后面的console.log(2),打印出2

所以最终输出为 3,1,2,从这个例子我们可以看出await后面语句的优先级是 低于 微任务的

generator

这一节我们来看下generator函数的不同用法以及对应的输出,你可以自己先思考下每个使用场景的输出,看下是否与最终结果一致

inte.jpg

场景一

1
2
3
4
5
6
7
8
function* test(){
yield setTimeout(()=>{
console.log(1)
},0)
}
const iterator = test()
iterator.next()
console.log(2)

程序运行过程如下:

  1. 执行test函数,拿到 遍历器对象
  2. 调用遍历器对象的 next 方法,执行test函数语句,遇到 yield,会暂停函数语句的执行,并执行yield后面的 setTimeout,将回调函数放入宏任务队列等待执行
  3. 执行外部的 console.log(2),打印出2
  4. 执行宏任务队列里的回调,打印出1

所以最终输出为 2,1

场景二

1
2
3
4
5
6
7
8
9
10
function* test(){
yield Promise.resolve(1).then(res=>{
console.log(res)
})
}
const iterator = test()
iterator.next()
setTimeout(()=>{
console.log(2)
},0)

程序运行过程如下:

  1. 执行test函数,拿到 遍历器对象
  2. 调用遍历器对象的 next 方法,执行test函数语句,遇到 yield,会暂停函数语句的执行,并执行yield后面的 Promise.resolve,将then指定的回调函数放入 微任务队列 等待执行
  3. 执行外部的 setTimeout,将指定的回调函数放入 宏任务队列 等待执行
  4. 同步代码执行完毕,首先清空微任务队列的任务,即打印出1
  5. 然后执行宏任务队列里的任务,即打印出2

所以最终输出为 1,2

6662.jpg

结语

async-await和generator的使用方式我们一定要烂熟于心,并且灵活运用,利用好它俩,是可以帮助我们很好地完成异步逻辑的编写,因此,对于它俩的掌握程度我认为一定要是精通,不然可能会在你做的项目中埋下大坑哦🤣~