一、async/await 是什么
async/await其实是Promise的语法糖,它能实现的效果都能用then链来实现,这也和我们之前提到的一样,它是为优化then链而开发出来的。从字面上来看,async是“异步”的简写,await译为等待,所以我们很好理解async声明function是异步的,await等待某个操作完成。当然语法上强制规定await只能出现在asnyc函数中
二、async/await的作用
- async是异步的简写,用于声明一个函数是异步执行。await用于等待一个异步方法执行完毕。
- await只能用于async函数中
- async 的作用就是将promise和生成器的效果融合了一下,promise主要用于解决回调地狱,也就是将异步代码同步封装。async同样能达到这个效果,而它达成效果依赖的则是生成器的特性。
三、async的使用方法
让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示:
async function f() {
return 1;
}
在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被包装在一个 resolved 的 promise 中。
例如,下面这个函数返回一个结果为 1 的 resolved promise:
async function f() {
return 1;
}
f().then(alert); // 1
我们也可以返回一个 promise,结果是一样的:
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
所以说,async 确保了函数返回一个 promise,也会将非 promise 的值包装进去。很简单,对吧?但不仅仅这些。还有另外一个叫 await 的关键词,它只在 async 函数内工作,也非常酷。
四、Await
语法如下:
// 只在 async 函数内工作
let value = await promise;
关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。
这里的例子就是一个 1 秒后 resolve 的 promise:
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // 等待,直到 promise resolve (*)
alert(result); // "done!"
}
f();
这个函数在执行的时候,“暂停”在了 (*) 那一行,并在 promise settle 时,拿到 result 作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”。
让我们强调一下:await 实际上会暂停函数的执行,直到 promise 状态变为 settled,然后以 promise 的结果继续执行。这个行为不会耗费任何 CPU 资源,因为 JavaScript 引擎可以同时处理其他任务:执行其他脚本,处理事件等。
相比于 promise.then,它只是获取 promise 的结果的一个更优雅的语法。并且也更易于读写。
五、总结
函数前面的关键字 async 有两个作用:
- 让这个函数总是返回一个 promise。
- 允许在该函数内使用
await。
Promise 前的关键字 await 使 JavaScript 引擎等待该 promise settle,然后:
- 如果有 error,就会抛出异常 —— 就像那里调用了
throw error一样。 - 否则,就返回结果。
这两个关键字一起提供了一个很好的用来编写异步代码的框架,这种代码易于阅读也易于编写。
有了 async/await 之后,我们就几乎不需要使用 promise.then/catch,但是不要忘了它们是基于 promise 的,因为有些时候(例如在最外层作用域)我们不得不使用这些方法。