async、await是promise的语法糖,使用async和await,可以让异步代码的书写像同步代码一样。
async关键字
将async关键字放在一个普通的function前面,会变成async function,那么async function和普通的function有什么不一样呢?
function hello() {
return 'hello'
}
hello()
// "hello"
async function hello() {
return 'hello'
}
hello()
// Promise {<fulfilled>: "hello"}
从上面的列子可以看出来,当在function 前面加上async后,该函数就会返回一个promise。
异步函数的特征之一就是保证函数的返回值是promise
因为async function的返回值是一个promise,要使用promise完成时的返回值,可以通过.then()进行获取
async function hello() {
return 'hello'
}
hello().then((str) => alert(str))
await关键字
await关键字需要和async关键字配合使用,也只能在异步函数中才会起作用。await可以放在任何异步的,基于promise的函数之前,它会阻塞代码的执行,知道promise完成,然后返回返回结果值。
async function hello() {
return new Promise((resolve) => {
setTimeout(() => {resolve('hello')}, 1000);
});
}
async function sayHello() {
await hello();
alert('done!')
}
sayHello();
// Promise {<pending>}
1s后会弹出“done!”
一些容易出问题的点
Q1:上面说到await会阻塞程序运行,直到异步函数hello()执行出结果,那么如果hello执行的结果是reject或者由于一些问题throw new Error()的话,await后面的代码还会执行吗?
答案:不能执行。
async function hello() {
return new Promise((resolve, reject) => {
reject('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
sayHello();
// Promise {<rejected>: "hello"}
async function hello() {
return new Promise((resolve, reject) => {
throw new Error('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
sayHello();
// Promise {<rejected>: Error: hello
at <anonymous>:3:11
at new Promise (<anonymous>)
at hello (<anonymous>:2:1…}
这两个情况下都不会在执行 alert('done!');
如果我们希望hello()运行中执行了reject或者是抛出错误后,不影响后面alert('hello')
的执行应该怎么办?增加try catch就行
async function sayHello() {
try {
await hello();
} catch (e) {
console.log(e)
}
alert('done!')
}
Q2:reject或者throw new error的捕获会继续向下传递吗?
答案:会,reject和error会一直冒泡出去
async function hello() {
return new Promise((resolve, reject) => {
throw new Error('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
sayHello().then((res) => {alert(res), (rej)=>{alert(rej)}})
// Promise {<fulfilled>: undefined}
窗口会弹出“Error: hello”,reject同理,输出“hello”
async function hello() {
return new Promise((resolve, reject) => {
throw new Error('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
async function catchFunc() {
try {
await sayHello()
} catch(e) {
alert(e)
}
}
catchFunc()
// Promise {<fulfilled>: undefined}
窗口会弹出“Error: hello”,reject同理,输出“hello”
Q3:下面两段代码有什么区别
代码片段1
async function hello() {
return new Promise((resolve, reject) => {
throw new Error('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
async function catchFunc() {
try {
sayHello()
} catch(e) {
alert(e)
}
}
catchFunc()
// Promise {<fulfilled>: undefined}
代码片段2:
async function hello() {
return new Promise((resolve, reject) => {
throw new Error('hello');
});
}
async function sayHello() {
await hello();
alert('done!')
}
async function catchFunc() {
try {
await sayHello()
} catch(e) {
alert(e)
}
}
catchFunc()
// Promise {<fulfilled>: undefined}
答案:代码片段2会弹出“Error:hello”,代码片段1不会。分析的原因应该是代码片段2是在sayHello函数执行完后进行捕获错误,所以可以捕获到错误,代码片段1没有使用await,捕获错误的时候函数sayHello异步执行还没报错,所以不会捕获到。
未完待续...
既然async/await是promise的语法糖,二者怎么转换呢?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。