什么是async/await
我们一般用Promise解决回调地狱的问题,用Promise.then来获取成功状态,但当多个相互依赖的请求时,代码可能会变成这样:
1 | p1.then(res => { |
显然不太好读。因此就有了async/await:
async函数返回一个Promise对象,可以使用promise对象的方法。可以看作多个异步操作,包装成的一个 Promise 对象await后面如果接的是promise对象,当Promise对象状态变化的时候,就会得到返回值,可以看作then的语法糖
基本用法
async函数
async函数返回的是一个Promise对象,如果函数中有返回值。则通过
Promise.resole()封装成Promise对象- 使用then方法添加回调函数获取return后面的值
- 使用catch 来捕获错误信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20async function fn() {
return "hello"
}
console.log(fn()); //Promise {<resolved>: "hello"} //返回的是一个Promise对象
fn().then(res => {
console.log(res) //"hellp"
})
//捕获错误信息
async function fn() {
let obj = {};
obj.run()
return "hello"
}
fn().then(res => {
console.log(res)
}).catch(err => {
console.log(err)//TypeError: obj.run is not a function
})
await()方法
只能在async函数中使用;
函数外面访问不到await及后面的表达式,如果需要在函数外部获取就需要在await前面加return。
await后面如果接的是promise对象,当
Promise对象状态变化的时候,得到返回值,如果接的是其他类型就直接返回。await命令就是内部then命令的语法糖。必须等待内部所有
await命令后面的Promise对象执行完,才会发生状态改变,才会执行then方法指定的回调函数任何一个
await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。1
2
3
4
5async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
f().then(res=>{console.log(res)}).catch(err=>{console.log(err);}) //出错了如果希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个
await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。1
2
3
4
5
6
7
8
9
10async function f() {
try {
await Promise.reject('出错了');
} catch(er) {
}
return await Promise.resolve('hello world');
}
f().then(res => console.log(res))
// hello world
async函数内部代码是同步执行的,执行时如果碰到await,就会先返回;等待await后面的表达式出结果之后再继续执行函数体内后面的语句,但是await不会阻塞async函数外的代码,await等待过程中函数外的代码正常向下同步执行。
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
26let p = new Promise((resolve) => {
setTimeout(() => {
resolve("promise")
}, 2000)
})
console.log("async 开始")
async function fn() {
console.log(1);
let a = await p;
console.log(a);
console.log(2);
return 3;
}
fn().next(res=>{
console.log(res)
})
console.log("async 结束")
//async 开始
//1
//async 结束
//(两秒后)promise
//2
//3
举例
1 | function http({ |
异常捕获
如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。
防止出错的方法就是我们将其放在try/catch代码块中。并且能够捕获异常。
1 | async function fn(){ |
异常捕获的封装
如果不想每次需要捕获异常的时候都写很多try/catch,也可以对异常捕获进行封装:
1 | function to(promise){ |
1 | // 使用举例 |