什么是async/await
async和await是ES8(ECMAScript 2017)引入的新特性,是对Promise更高层次的抽象,能更方便地使用异步函数。
async函数本质上是 Generator 函数的语法糖。async函数返回的是一个Promise对象,await表达式会阻塞代码执行,等待Promise对象的解决,然后获取解决值。
async函数的使用
async函数的定义方式如下:
async function foo() { return 'bar'; } foo().then((result) => console.log(result)); // 'bar'
async函数通过async
关键字定义,函数体内部通过return
返回一个值。
运行方式与普通函数相同,可以直接在函数名后加一对括号调用。
async函数返回的是一个Promise对象,可以使用.then()
或者await
来获取函数返回的值。
-- -------------------- ---- ------- ----- -------- ----- - ------ ------ - ------------------- -- --------------------- -- ----- ----- -------- ----- - ----- - - ----- ------ --------------- -- ----- - ------
上面的代码中,baz()
函数内部调用了foo()
函数并使用了await
关键字阻塞了后面语句的执行,直到foo()
函数返回后,才会返回解决值"bar",并赋值给a
变量输出到控制台。
await
关键字实际上是将一个Promise对象等待并得到解决值,因此我们也可以用await
关键字去获取其他返回Promise的API的值。
-- -------------------- ---- ------- -------- ----------- - ------ --- ----------------- -- - ------------- -- - -------------- -------- -- ------ --- - ----- -------- ----- - ----- - - ----- ------------ --------------- -- ------ ------ - ------
错误处理
当Promise对象被拒绝(rejected)时,我们希望能够捕获到并进行相应的处理。
- 使用
.catch()
当async函数中会被拒绝的Promise对象被拒绝时,我们可以使用.catch()
对其进行捕获并进行处理。
async function foo() { const promise = Promise.reject('Rejected.'); await promise.catch((err) => console.log(err)); // 'Rejected.' }
try
...catch
语句
类似于同步代码的异常处理方式,我们可以使用try
...catch
语句来捕获异常。
-- -------------------- ---- ------- ----- -------- ----- - --- - ----- ------- - ---------------------------- ----- -------- - ----- ----- - ----------------- -- ----------- - - ------
当Promise对象被拒绝时,将会直接跳转到catch
语句块内,执行后面的代码。
并发执行多个异步任务
在需要并行执行多个异步任务的情况下,我们可以将多个任务使用.then()
连接,或使用Promise.all()来执行并行任务,但这些方法都比较麻烦和容易出错。使用async/await,我们可以更方便、优雅地执行异步任务。
async function parallel() { const [a, b] = await Promise.all([promiseA(), promiseB()]); }
上面的代码中,我们使用了数组解构将Promise.all()返回的两个Promise对象解构到变量a
和b
中。
顺序执行多个异步任务
我们也可以将异步任务按顺序执行,需要注意的是await会阻塞后面的表达式,因此在多个await调用是,我们需要按照顺序将它们依次调用。
async function sequence() { const a = await promiseA(); const b = await promiseB(); }
其他注意事项
1. async函数返回的是一个Promise对象
因此,在async函数内部不需要使用return Promise.resolve(value)
,直接使用return value
即可。
2. async函数内部能够使用大多数的Promise API。
例如Promise.all()
、Promise.race()
等等。
3. await只能出现在async函数体中。
如果我们想要在普通函数内使用await,可以声明一个异步的立即执行函数(IIFE,Immediately-invoked function expression)。
(async function foo() { const a = await promiseA(); })();
总结
async/await模式是我们在异步处理中非常实用的工具。通过使用async/await模式,不仅能够简化异步代码的写法,还能够使代码更加合理清晰,易于维护。需要注意的是,async必须要配合await使用,否则async函数的返回值可能会出现问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64716038968c7c53b0f40403