ZetCode

JavaScript async 关键字

最后修改于 2025 年 4 月 16 日

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

async 关键字

async 关键字用于在 JavaScript 中声明异步函数。一个 async 函数总是返回一个 Promise,无论是已解决还是已拒绝。这允许编写看起来像同步的异步代码。

Async 函数与 await 关键字一起使用,暂停执行直到 Promise 被确定。此语法简化了 Promise 的使用,并避免了回调地狱。Async/await 使异步代码更易于阅读和维护。

如果没有 async/await,异步操作需要链接 .then() 调用或使用回调函数。async/await 语法为这些模式提供了一个更简洁的替代方案,同时保持相同的功能。

基本 async 函数

以下示例演示了 async 关键字的基本用法。

main.js
async function greet() {
    return 'Hello, World!';
}

greet().then(message => console.log(message));

这个简单的 async 函数返回一个字符串,该字符串会自动包装在一个已解决的 Promise 中。我们调用该函数并使用 .then() 来处理结果。该函数看起来是同步的,但实际上是异步工作的。

$ node main.js
Hello, World!

带有 await 的 async 函数

async 函数的真正力量在于与 await 结合使用。

main.js
function resolveAfter2Seconds() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve('resolved');
        }, 2000);
    });
}

async function asyncCall() {
    console.log('calling');
    const result = await resolveAfter2Seconds();
    console.log(result);
}

asyncCall();

此示例显示了一个等待 Promise 被解决的 async 函数。await 关键字会暂停执行,直到 Promise 被确定。代码看起来是顺序执行的,但实际上是异步运行的,不会阻塞主线程。

$ node main.js
calling
resolved

使用 try/catch 进行错误处理

Async 函数允许使用 try/catch 块进行错误处理。

main.js
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Error:', error);
    }
}

fetchData();

此示例演示了如何在 async 函数中进行错误处理。try 块包含可能失败的异步操作。任何错误都会在 catch 块中捕获,类似于同步错误处理。

$ node main.js
Error: TypeError: fetch failed

使用 Promise.all 进行并行执行

可以使用 Promise.all 并行执行多个异步操作。

main.js
async function fetchMultiple() {
    const [users, posts] = await Promise.all([
        fetch('https://api.example.com/users').then(res => res.json()),
        fetch('https://api.example.com/posts').then(res => res.json())
    ]);
    
    console.log('Users:', users);
    console.log('Posts:', posts);
}

fetchMultiple();

此示例显示了如何同时运行多个异步操作。Promise.all 等待所有 Promise 被解决后才会继续。这比依次等待每个操作更有效率。

$ node main.js
Users: [...]
Posts: [...]

Async 箭头函数

箭头函数也可以声明为 async。

main.js
const fetchUser = async (userId) => {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    return response.json();
};

fetchUser(42).then(user => console.log(user));

此示例演示了一个 async 箭头函数。语法类似于常规箭头函数,但带有 async 关键字。该函数返回一个 Promise,该 Promise 以已解析的 JSON 数据解析为结果。

$ node main.js
{ id: 42, name: 'John Doe' }

Async 类方法

类方法也可以声明为 async。

main.js
class DataFetcher {
    async getData(url) {
        const response = await fetch(url);
        return response.json();
    }
}

const fetcher = new DataFetcher();
fetcher.getData('https://api.example.com/data')
    .then(data => console.log(data));

此示例显示了类中的一个 async 方法。该方法遵循与独立 async 函数相同的规则。它返回一个 Promise,该 Promise 以获取的数据解析为结果。

$ node main.js
{ data: [...] }

实际用例:API 请求

这是一个使用 async/await 进行 API 请求的实际示例。

main.js
async function getWeather(city) {
    try {
        const response = await fetch(`https://api.weather.com/${city}`);
        if (!response.ok) {
            throw new Error('City not found');
        }
        const weather = await response.json();
        return weather;
    } catch (error) {
        console.error('Failed to fetch weather:', error);
        return null;
    }
}

getWeather('london').then(weather => {
    if (weather) {
        console.log(`Temperature: ${weather.temp}°C`);
    }
});

此示例演示了一个用于获取天气数据的真实世界 async 函数。它包括错误处理和适当的响应检查。async/await 语法使代码比 Promise 链更具可读性。

$ node main.js
Temperature: 15°C

来源

async - 语言参考

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

作者

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

查看 所有 JavaScript 教程。