ES6-async函数

什么是 async 函数

async 函数算是一个语法糖,使异步函数、回调函数在语法上看上去更像同步函数

1
2
3
4
5
6
7
8
9
10
11
12
async function asyncLoadData (urlOne, urlTwo) {
let dataOne = await loadData (urlOne)
let dataTwo = await loadData (urlTwo)
}
```

在上面的代码中,`loadData`方法是异步获取数据的方法 可以看到,在 async 函数中,出现了一个陌生的关键字`await`——这个关键字只能够在 async 函数中使用,否则将会报错,它的意思是紧跟在其后面的表达式需要被等待执行结果 上面的代码其实和 generator 函数有点类似呢?写成 generator 的话,应该是类似下面的函数:
```js
function * asyncLoadData (urlOne, urlTwo) {
let dataOne = yield loadData (urlOne)
let dataTwo = yield loadData (urlTwo)
}

但是 generator 与 async 的区别并不仅仅是将*改为async,将yield改为await

generator 和 async 的区别

内置执行器 我们知道 generator 函数需要通过调用next()方法,才能往后执行到下一个yield,但是 async 函数却不需要,它能够自动向后执行 更易理解 如果你不曾了解过 generator 和 async 函数,那我想你一定无法直观的理解 generator,但是却可以轻易理解 async,这一点仅从字面意思就变现的很清楚了 更适用 yield命令后面只能跟随TrunkPromise,但是await后面除了可以是Promise,也可以是普通类型,但是这样就和同步没有任何区别了 返回值 generator 返回的是一个遍历器对象,而 async 返回的是一个 Promise 对象

async 语法

async 返回一个Promise,因此这个函数可以通过then添加回调函数,那么怎么向then中的回调添加参数呢?async 函数中 return 的结果将作为回调的参数

1
2
3
4
5
6
7
8
9
10
async function test () {
return 'this is a test async function'
}

test().then(
resolveArg => console.log(resolveArg)
)

// 输出结果
// this is a test async function

同样,当 async 函数内部抛出一个错误时,也会被 catch 到,下面三种 catch 错误的方式都可以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
async function errorTest () {
throw new Error('this is an error');
}

// 在 then 的回调中捕获错误
errorTest().then(
resolve => console.log(resolve),
error => console.log(error)
)

// 在 Promise 的 catch 方法中捕获
errorTest().catch(
error => console.log(error)
)

// 在 try...catch 语句中捕获
try{
errorTest()
} catch (error) {
console.log(error)
}
```

### await 命令

前面说了`await`命令后面可以是`Promise`也可以是普通数据类型,但如果是普通数据类型的话,会自动转换成状态为`resolve`的`Promise` 如果`await`后面的`Promise`状态转变成了`reject`,那么整个 async 函数都会停止执行,并且抛出相应的错误。即使这里没有`return`,也一样可以传入错误回调的参数 所以当一个 async 函数中有多个 `await`命令时,如果不想因为一个出错而导致其与的都无法执行,应将`await`放在`try...catch`语句中执行
```js
async function testAwait () {
try {
await func1()
await func2()
await func3()
} catch (error) {
console.log(error)
}
}

并发执行 await 命令

当一个 async 函数中有多个await时,这些 await是继发执行的,只有当前一个await后面的方法执行完毕后,才会执行下一个 如果我们前后的方法由依赖关系,继发执行是没有问题的,但是如果并没有任何关系的话,这样就会很耗时,所以需要让这些await命令同时执行,也就是并发执行

1
2
3
4
5
6
7
8
// 方法 1
let [res1, res2] = await Promise.all([func1(), func2()])

// 方法 2
let func1Promise = func1()
let func2Promise = func2()
let res1 = await func1Promise
let res2 = await func2Promise
  • 版权声明: 本博客所有文章,未经许可,任何单位及个人不得做营利性使用!转载请标明出处!如有侵权请联系作者。
  • Copyrights © 2015-2020 翟天野

请我喝杯咖啡吧~