async/await
是一种用来处理Promise
的特殊语法,同时给人的感觉又非常优雅。
Async 函数
我们先从async
开始:
async function f() {
return 1;
}
在函数前的async
表示该函数总是返回一个Promise
。当代码中没有返回Promise
时,js会自动封装好一个Promise
返回该值。
例如,上面的代码返回一个Promise
,结果为1:
async function f() {
return 1;
}
f().then(alert); // 1
特地返回一个Promise
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
所以说async
函数总是返回Promise
。接下来的await
关键字更酷。
Await 关键字
// 只在async函数里面才有用
let value = await promise;
await
用来使Javascript
等待Promise
对象执行。如果await
的是 promise对象会造成异步函数停止执行并且等待Promise
的resolve
, 如果等的是正常的表达式则立即执行。
看下面的例子:
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // wait till the promise resolves (*)
alert(result); // "done!"
}
其实async/await
差不多就是Promise.then()
更优雅,可读性更强的写法。
几个需要注意的点
- 在普通的函数里不能使用
await
如果在没有async
声明的函数使用await
就会报错。
function f() {
let promise = Promise.resolve(1);
let result = await promise; // Syntax error
}
-
thenable
对象
和Promise.then
一样,await
也可以使用thenable对象(有可调用的then
方法)。例如一个对象可能并不是Promise
, 但有then
方法可以调用,就可以使用await
了。
class Thenable {
constructor(num) {
this.num = num;
}
then(resolve, reject) {
alert(resolve); // function() { native code }
// resolve with this.num*2 after 1000ms
setTimeout(() => resolve(this.num * 2), 1000); // (*)
}
};
async function f() {
// waits for 1 second, then result becomes 2
let result = await new Thenable(1);
alert(result);
}
f();
-
class
里使用
class Waiter {
async wait() {
return await Promise.resolve(1);
}
}
new Waiter()
.wait()
.then(alert); // 1
异常处理
async function f() {
await Promise.reject(new Error("Whoops!"));
}
// 一样的
async function f() {
throw new Error("Whoops!");
}
try..catch
async function f() {
try {
let response = await fetch('http://no-such-url');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
async function f() {
try {
let response = await fetch('/no-user-here');
let user = await response.json();
} catch(err) {
// catches errors both in fetch and response.json
alert(err);
}
}
f();
async function f() {
let response = await fetch('http://no-such-url');
}
// f() becomes a rejected promise
f().catch(alert); // TypeError: failed to fetch // (*)
和Promise.all
搭配使用
// wait for the array of results
let results = await Promise.all([
fetch(url1),
fetch(url2),
...
]);
总结
在函数前面的async
关键字有两个作用:
- 让函数返回
Promise
对象 - 在函数中可以使用
await
await
用来使Javascript
等待Promise
对象的执行
网友评论