ZetCode

JavaScript await 关键字

最后修改于 2025 年 4 月 16 日

在本文中,我们将展示如何使用 JavaScript 中的 await 关键字处理异步操作。

await 关键字

await 关键字用于暂停 async 函数的执行,直到 Promise 被解决。它只能在 async 函数内部使用。这使得异步代码看起来更像同步代码,并且行为也更像同步代码。

当使用 await 时,它会等待 Promise 稳定下来。如果 Promise 被解决,它将返回解决的值。如果被拒绝,它将抛出拒绝值。这简化了处理 Promise 的过程,并避免了回调地狱。

await 关键字始终与 Promise 一起使用。它使异步代码更具可读性和可维护性。错误处理可以使用 try/catch 块完成,类似于同步代码。

基本 await 示例

以下示例演示了 await 关键字与简单 Promise 的基本用法。

main.js
async function fetchData() {
    const data = await new Promise((resolve) => {
        setTimeout(() => resolve('Data received'), 1000);
    });
    console.log(data);
}

fetchData();

此示例创建一个 Promise,该 Promise 在 1 秒后解决。 await 关键字暂停执行,直到 Promise 解决。然后,将解决的值分配给 data 变量。最后,将该值记录到控制台。

$ node main.js
Data received

使用 Fetch API 的 Await

await 关键字通常与 Fetch API 一起使用。

main.js
async function getUser() {
    const response = await fetch('https://api.github.com/users/octocat');
    const data = await response.json();
    console.log(data.name);
}

getUser();

此示例从 GitHub 的 API 获取用户数据。第一个 await 等待 fetch 请求完成。第二个 await 等待响应被转换为 JSON。这展示了 await 如何干净地链接异步操作。

$ node main.js
The Octocat

使用 try/catch 进行错误处理

使用 await 的错误处理可以使用 try/catch 块完成。

main.js
async function fetchWithErrorHandling() {
    try {
        const response = await fetch('https://invalid.url');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Error:', error.message);
    }
}

fetchWithErrorHandling();

此示例演示了 fetch 请求失败时的错误处理。 try 块包含异步操作。如果任何 Promise 被拒绝,执行将跳转到 catch 块。这提供了一种干净的方式来处理异步代码中的错误。

$ node main.js
Error: fetch failed

使用多个 Promise 的 Await

多个 Promise 可以按顺序或并行等待。

main.js
async function getMultipleData() {
    const promise1 = Promise.resolve('First');
    const promise2 = Promise.resolve('Second');
    
    const result1 = await promise1;
    const result2 = await promise2;
    
    console.log(result1, result2);
}

getMultipleData();

此示例显示了多个 Promise 的顺序等待。每个 await 都会暂停执行,直到其 Promise 解决。对于并行执行, Promise.all() 将更有效。这演示了等待多个操作的基本模式。

$ node main.js
First Second

使用 Promise.all 的 Await

Promise.all() 可以与 await 一起用于并行执行。

main.js
async function fetchInParallel() {
    const urls = [
        'https://api.github.com/users/octocat',
        'https://api.github.com/users/torvalds'
    ];
    
    const promises = urls.map(url => fetch(url).then(res => res.json()));
    const results = await Promise.all(promises);
    
    results.forEach(user => console.log(user.name));
}

fetchInParallel();

此示例并行从多个 URL 获取数据。 Promise.all() 等待所有 Promise 解决。 await 暂停,直到所有请求完成。这比按顺序等待每个请求更有效。

$ node main.js
The Octocat
Linus Torvalds

在顶级代码中使用 Await

在现代 JavaScript 中,await 可以在顶级代码中使用。

main.js
const data = await Promise.resolve('Top-level await');
console.log(data);

此示例演示了顶级 await,可在 ES 模块中使用。 await 关键字可以在模块作用域内的 async 函数之外使用。这简化了需要等待异步操作的初始化代码。

$ node main.js
Top-level await

实际用例:文件读取

这是一个使用 await 进行文件操作的实际示例。

main.js
import { promises as fs } from 'fs';

async function readFiles() {
    try {
        const content = await fs.readFile('example.txt', 'utf-8');
        console.log(content);
    } catch (err) {
        console.error('Error reading file:', err);
    }
}

readFiles();

此示例使用 Node.js fs 模块异步读取文件。 await 关键字等待文件读取操作完成。错误处理使用 try/catch 完成。这显示了 await 的一个常见现实世界用例。

$ node main.js
File content here...

来源

await - 语言参考

在本文中,我们演示了如何在 JavaScript 中使用 await 关键字进行异步编程。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。