认识
一、认识
async/await
也是异步编程的一种解决方案,是 Generator
函数的语法糖,同时基于Promise
。async
函数就是将 Generator
函数的星号(*
)替换成async
,将yield
替换成await
,仅此而已。主要的作用是用同步的方式,执行异步的操作
二、语法
2.1 async await return new Prmose
function x(value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value % 2 === 0) {
resolve('1 成功');
} else {
reject('1 失败');
}
}, 3000);
});
}
async function y() {
const result = await x(4);
console.log(result);
}
y();
2.2 async await await new Promise
async function x(value) {
return await new Promise((resolve, reject) => {
setTimeout(() => {
if (value % 2 === 0) {
resolve('1 成功');
} else {
reject('1 失败');
}
}, 3000);
});
}
async function y() {
const result = await x(4);
console.log(result);
}
y();
2.3 async await async.then async.catch
async
函数返回一个 Promise
对象,因此, async
函数可以后面调用 .then
方法 和 .catch
方法。必须等到内部所有await
命令后面的 Promise
对象执行完,才会发生状态改变,除非遇到return
语句或者抛出错误。
-
.then
:async
函数内部return
语句返回的值,会成为then
方法回调函数的参数。 -
.catch
:async
函数内部抛出错误,会导致返回的Promise
对象变为reject
状态。抛出的错误对象会被catch
方法回调函数接收到。
function x(value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value % 2 === 0) {
resolve('1 成功');
} else {
reject('1 失败');
}
}, 3000);
});
}
async function y() {
const result = await x(4);
console.log(result);
return 0;
}
y()
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
三、检测
描述: 如何判断传入的函数是否标记了 async
3.1 Symbol.toStringTag
function isAsyncFunction(func) {
return func[Symbol.toStringTag] === "AsyncFunction";
}
console.log("function >>> ", isAsyncFunction(() => {}));
console.log("async function >>> ", isAsyncFunction(async () => {}));
console.log("function Promise >>> ", isAsyncFunction(() => {return new Promise()}));
3.2 Object.prototype.toString.call
function isAsyncFunction(func) {
return Object.prototype.toString.call(func) === "[object AsyncFunction]";
}
console.log("function >>> ", isAsyncFunction(() => {}));
console.log("async function >>> ", isAsyncFunction(async () => {}));
console.log("function Promise >>> ", isAsyncFunction(() => {return new Promise()}));
四、调用
4.1 函数
4.2 顶层
早期的语法规定是,await
命令只能出现在 async
函数内部,否则都会报错。
五、问题
5.1 async vs generator
-
内置执行器:
Generator
函数的执行必须靠执行器,所以才有了co
模块,而async
函数自带执行器。也就是说,async
函数的执行,与普通函数一模一样,只要一行。 -
更好的语义:
async
和await
,比起星号和yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。 -
更广的适用性:
co
模块约定,yield
命令后面只能是Thunk
函数或Promise
对象,而async
函数的await
命令后面,可以是Promise
对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即resolved
的Promise
对象)。 -
返回值是 Promise:
async
函数返回值是Promise
对象,比Generator
函数返回的Iterator
对象方便,可以直接使用then()
方法进行调用