跳到主要内容

认识

一、认识


async/await 也是异步编程的一种解决方案,是 Generator 函数的语法糖,同时基于Promiseasync 函数就是将 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函数的执行,与普通函数一模一样,只要一行。

  • 更好的语义: asyncawait,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

  • 更广的适用性: co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolvedPromise 对象)。

  • 返回值是 Promise: async 函数返回值是 Promise 对象,比 Generator 函数返回的 Iterator 对象方便,可以直接使用 then() 方法进行调用

参考资料


你不知道的 async、await 魔鬼细节