本文已参与「新人创作礼」活动,一起开启掘金创作之路。
异步函数async function
async关键字用于声明一个异步函数:
- async是asynchronous单词的缩写,异步、非同步;
- sync是synchronous单词的缩写,同步、同时;
async异步函数可以有很多中写法:
async function bar() {}
const baz = async function () {};
const foo = async () => {};
class Person {
async fn() {}
}
异步函数的执行流程
- 异步函数的内部代码执行过程和普通函数是一致的,默认情况下也是被同步执行;
async function bar() {
console.log("bar exec");
}
console.log("script start");
bar();
console.log("script end");
// script start
// bar exec
// script end
-
异步函数有返回值时,和普通函数会有区别:
- 异步函数的返回值会被包裹到Promise.resolve中;
- 如果异步函数的返回值本身是个Promise对象,那么Promise.reolve的状态会由这个Promise对象决定;
- 如果异步函数的返回值是一个thenable对象,那么会由该对象的then方法来决定;
async function bar() {
// 1.返回一个普通值
// return "hhh";
// 2.返回一个Promise对象
// return new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve("xixixi");
// }, 1000);
// });
// 3.返回一个thenable对象
return {
name: "obj",
then(resolve) {
resolve(this.name);
},
};
}
const result = bar();
result.then((value) => {
console.log(value);
});
- 如果我们在async函数中抛出异常,那么程序并不会像普通函数那样报错,而是作为Promise的reject来传递;
async function foo() {
console.log("foo start");
throw "foo err";
console.log("foo end");
}
const result = foo();
result.catch((reason) => {
console.log(reason);
});
// foo start
// foo err
await关键字
-
async函数另外一个特殊之处在于它内部能够使用await关键字,而普通函数中是不可以的;
-
await关键字有什么特点呢?
- 通常使用await是后面会跟上一个表达式,这个表达式会返回一个Promise;
- 那么await会等到Promise的状态变成fulfilled状态,之后继续执行异步函数;
-
如果await后面是一个普通的值,那么会直接返回这个值;
-
如果await后面是一个thenable的对象,那么会根据对象的then方法调用来决定后续的值;
-
如果await后面的表达式,返回的Promise是reject的状态,那么会将这个reject结果直接作为函数的Promise的reject值返回,并且函数会结束执行;
function requestData() {
return new Promise((resolve, reject) => {
console.log("request data");
setTimeout(() => {
resolve(111);
}, 1000);
});
}
async function bar() {
console.log("bar start");
const result1 = await requestData();
// await之后的代码相当于卸载promise.then方法之中
console.log("result1:", result1);
const result2 = await requestData();
console.log("result2:", result2);
console.log("bar end");
}
console.log("script start");
bar();
console.log("script end");
// script start
// bar start
// request data
// script end
// result1: 111
// request data
// result2: 111
// bar end
async function foo() {
const result1 = await 111;
console.log("result1:", result1);
const result2 = await {
then(resolve) {
resolve(222);
},
};
console.log("result2:", result2);
}
console.log("script start");
foo();
console.log("script end");
// script start
// script end
// result1: 111
// result2: 222
async function baz() {
console.log("baz start");
const result = await new Promise((resolve, reject) => {
reject("bar exec err");
});
console.log("result:", result);
console.log("baz end");
}
baz().catch((reason) => {
console.log("bar err:", reason);
});
// baz start
// bar err: bar exec err