async function

2026-07-20 13:48:30 秘境攻略

描述

async function 声明创建一个 AsyncFunction 对象。每次调用异步函数时,都会返回一个新的 Promise 对象,该对象将会被解决为异步函数的返回值,或者被拒绝为异步函数中未捕获的异常。

异步函数可以包含零个或者多个 await 表达式。await 表达式通过暂停执行使返回 promise 的函数表现得像同步函数一样,直到返回的 promise 被兑现或拒绝。返回的 promise 的解决值会被当作该 await 表达式的返回值。使用 async/await 关键字就可以使用普通的 try/catch 代码块捕获异步代码中的错误。

备注:await 关键字只在常规 JavaScript 代码中的异步函数内有效。如果你在异步函数体之外使用它,则会抛出 SyntaxError。

await 可以单独与 JavaScript 模块一起使用。

备注:async/await 的目的在于简化使用基于 promise 的 API 时所需的语法。async/await 的行为就好像搭配使用了生成器和 promise。

异步函数总是返回一个 promise。如果一个异步函数的返回值看起来不是 promise,那么它将会被隐式地包装在一个 promise 中。

例如,请看以下代码:

jsasync function foo() {

return 1;

}

类似于:

jsfunction foo() {

return Promise.resolve(1);

}

备注:

即使异步函数的返回值看起来像是被包装在了一个 Promise.resolve 中,但它们不是等价的。

如果给定的值是一个 promise,异步函数会返回一个不同的引用,而 Promise.resolve 会返回相同的引用,

当你想要检查一个 promise 和一个异步函数的返回值是否等价时,这可能是一个麻烦。

jsconst p = new Promise((res, rej) => {

res(1);

});

async function asyncReturn() {

return p;

}

function basicReturn() {

return Promise.resolve(p);

}

console.log(p === basicReturn()); // true

console.log(p === asyncReturn()); // false

异步函数的函数体可以被看作是由零个或者多个 await 表达式分割开来的。从顶层代码直到(并包括)第一个 await 表达式(如果有的话)都是同步运行的。因此,不包含 await 表达式的异步函数是同步运行的。然而,如果函数体内包含 await 表达式,则异步函数就一定会异步完成。

例如:

jsasync function foo() {

await 1;

}

等价于:

jsfunction foo() {

return Promise.resolve(1).then(() => undefined);

}

每个 await 表达式之后的代码可以被认为存在于 .then 回调中。通过这种方式,可以通过函数的每个可重入步骤来逐步构建 promise 链。而返回值构成了链中的最后一个环。

在接下来的示例中,我们依次 await 两个 promise,整个 foo 函数的执行将会被分为三个阶段。

foo 函数的第一行将会同步执行,其中 await 配置了待定的 promise。然后 foo 的进程将被暂停,并将控制权交还给调用 foo 的函数。

一段时间后,当第一个 promise 被兑现或拒绝的时候,控制权将重新回到 foo 内。第一个 promise 的兑现结果(如果没有被拒绝的话)将作为 await 表达式的返回值。在这里 1 被赋值给 result1。程序继续执行,并计算第二个 await 表达式。同样的,foo 的进程将被暂停,并交出控制权。

一段时间后,当第二个 promise 被兑现或拒绝的时候,控制权将重新回到 foo。第二个 promise 的兑现结果将作为第二个 await 表达式的返回值。在这里 2 被赋值给 result2。程序继续执行到返回表达式(如果有的话)。默认的返回值 undefined 将作为当前 promise 的兑现值被返回。

jsasync function foo() {

const result1 = await new Promise((resolve) =>

setTimeout(() => resolve("1")),

);

const result2 = await new Promise((resolve) =>

setTimeout(() => resolve("2")),

);

}

foo();

注意:promise 链不是一次就构建好的,相反,promise 链是随着控制权依次在异步函数中交出并返回而分阶段构建的。因此在处理并发异步操作时,我们必须小心错误处理。

例如,在下面代码中,即使在 promise 链中进一步配置了 .catch 处理方法,也会抛出一个未处理的 promise 被拒绝的错误。这是因为 p2 直到控制从 p1 返回后才会连接到 promise 链。

jsasync function foo() {

const p1 = new Promise((resolve) => setTimeout(() => resolve("1"), 1000));

const p2 = new Promise((_, reject) => setTimeout(() => reject("2"), 500));

const results = [await p1, await p2]; // 不要这么写!请使用 Promise.all 或者 Promise.allSettled。

}

foo().catch(() => {}); // 尝试捕捉所有的错误...

async function 声明的行为类似于 function 声明,它会被提升到其作用域的顶部,并且可以在其作用域的任何位置被调用,并且只能在其他上下文中被重新声明。

分什么什么什么成语
《塞尔达传说王国之泪》黑暗套装怎么获得?黑暗套装获取攻略