
在我之前的教程中,我们介绍了 JavaScript 中 Promise 的基础知识。我在文章的最后说,promise 允许我们异步运行我们的代码。
在本教程中,我们将学习 JavaScript 中的 async 和 await 关键字,它们使我们能够有效地使用 Promise 并编写更简洁的异步代码。
async 函数让我们从异步函数开始讨论。考虑以下问候语函数:
function greet() {
return "Hello, World!";
}
// Outputs: Hello, World!
console.log(greet());
这只是我们之前见过的常规 JavaScript 函数。它所做的只是返回一个字符串,上面写着“Hello, World!”不过,我们可以将其变成异步函数,只需在其前面添加 async 即可,如下所示:
立即学习“Java免费学习笔记(深入)”;
async function greet() {
return "Hello, World!";
}
// Outputs: Promise { <state>: "fulfilled", <value>: "Hello, World!" }
console.log(greet());
这一次,该函数返回一个 Promise 对象,其 state 属性设置为已完成,值设置为 Hello, World! 换句话说,promise 已成功解析。
我们仍然返回字符串“Hello, World!”在函数定义里面。但是,使用 async 关键字意味着返回值将包装在已解析的 Promise 对象中。已解决的 Promise 的值将与我们从 async 函数返回的值相同。
您还可以从 async 函数返回您自己的承诺,如下所示:
async function greet() {
return Promise.resolve("Hello, World!");
}
// Outputs: Hello, World!
greet().then((value) => console.log(value));
基本上,async 关键字帮助我们定义始终返回承诺的函数。您可以自己显式返回一个 Promise,也可以让函数将任何不是 Promise 的返回值包装到 Promise 中。
await 关键字任何 async 函数都可以包含零个或多个 await 表达式。重要的是要记住 await 关键字仅在 async 函数内有效。 await 关键字用于等待 Promise 解析或拒绝,然后获取已完成的值。
我们使用 await 关键字,语法如下:
await expression
表达式可以是原生的Promise,这种情况下直接使用,原生等待。在这种情况下,不会有对 then() 的隐式调用。表达式可以是 thenable 对象,在这种情况下,将通过调用 then() 方法构造一个新的 Promise 。该表达式也可以是不可thenable 的值。在这种情况下,将构建一个已经实现的 Promise 供我们使用。
假设一个承诺已经兑现了。 async 函数的执行仍然会暂停,直到下一个tick。记住这一点很重要。
以下是在 async 函数中使用 await 关键字的示例:
async function greet() {
let greeting = await "Hello, World!";
return greeting;
}
// Outputs: [Function: Promise]
console.log(greet().constructor);
// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
这是在显式使用 Promise 时将 await 关键字与 async 函数结合使用的另一个示例:
async function greet() {
let greeting = new Promise((resolve) => {
setTimeout(() => {
resolve("Hello, World!");
}, 2000);
});
return greeting;
}
// Outputs: [Function: Promise]
console.log(greet().constructor);
// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
这一次,我们明确使用了一个在 2 秒内解析的 Promise。因此,“Hello, World”问候语将在两秒后打印。
我们现在将编写两个不同的问候函数并查看它们输出结果的顺序。
function n_greet(person) {
return `Hello, ${person}!`;
}
async function a_greet(person) {
let greeting = await `Hello, ${person}!`;
return greeting;
}
我们的第一个函数 n_greet() 是一个返回字符串作为输出的普通函数。我们的第二个函数是 async 函数,它在 await 关键字之后使用表达式。本例中的返回值是一个已经履行的承诺。
这是调用所有这些函数并记录输出的代码片段:
a_greet("Andrew").then((msg) => console.log(msg));
console.log(n_greet("Adam"));
/* Output in order:
Hello, Adam!
Hello, Andrew! */
问候 Adam 的 n_greet() 函数调用已结束。然而,他在输出中首先受到欢迎。这是因为函数调用直接返回一个字符串。
a_greet() 函数调用是在开始时向 Andrew 打招呼的,它导致了一个已经履行的承诺的构建。然而,执行仍然暂停,直到下一个时钟周期。这就是为什么输出问候语出现在对 Adam 的问候语之后。
现在,我们将定义一个稍微复杂一点的 async 函数,其中包含多个语句。这些语句之一将具有 await 关键字。您将看到,在 async 函数中使用 await 关键字会暂停执行 await 语句之后的其他语句。
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function aa_greet(person) {
console.log("Before Await...");
await timeout(2000);
let greeting = `Hello, ${person}!`;
console.log("After Await...");
return greeting;
}
我们的 async 函数包含一个显式定义的 Promise,前面带有 await 关键字。这意味着 await 关键字将等待 Promise 被履行,然后返回已履行的值。该承诺将需要 2 秒才能实现,因此大约 2 秒后我们应该在控制台日志中看到“After Await...”。
这是代码片段,它将记录我们的 async 函数的一些语句:
console.log("Before Greeting Function...");
aa_greet("Monty").then((msg) => console.log(msg));
console.log("After Greeting Function...");
/* Output in Order
23:42:15.327 Before Greeting Function...
23:42:15.331 Before Await...
23:42:15.331 After Greeting Function...
23:42:17.333 After Await...
23:42:17.333 Hello, Monty! */
首先记录字符串“Before Greeting Function...”,因为这是我们进行的第一次调用。之后,我们调用 aa_greet() 函数。这会导致输出字符串“Before Await...”。然后,浏览器遇到 await 关键字。所以它等待承诺解决。与此同时,aa_greet()函数之外的代码继续执行。这就是为什么我们在下一个日志条目中得到“After Greeting Function...”字符串作为输出。
一旦承诺得到解决,浏览器就会继续执行,我们会得到“After Await...”作为输出。最后,我们解析的问候语作为承诺返回,因为我们使用 async 函数。我们对这个已解决的 Promise 调用 then() 方法并记录“Hello, Monty!”到控制台。
async 和 await
await 关键字的一个常见用例是从远程 API 获取数据。这允许比嵌套回调或承诺链更干净的代码。
async function getData() {
// use the fetch API to fetch data from an API endpoint
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
// check if the response is okay (HTTP status code 200-299)
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// parse the response as JSON
const data = await response.json();
return data;
}
在此函数中,首先我们等待对 API 查询的初始响应。如果响应正常,我们就会等待 JSON 格式的完整响应数据。我们返回 JSON 数据,但请记住,由于这是一个异步函数,因此我们实际上返回一个最终解析为该数据的 Promise。因此,如果您想访问结果数据,您必须再次使用类似await关键字的东西!
const data = await getData();
在上一篇教程中了解了 Promise 对象后,我们在本教程中讨论了 async 函数和 await 关键字。您现在应该能够编写自己的 async 函数,使用 await 关键字来使用更清晰、更易读的代码实现基于 Promise 的行为。
以上就是探索 JavaScript 中 async 和 wait 的威力的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号