Async/Await 教程

概述

在现代 JavaScript 编程中,异步操作是非常常见的。为了更方便地处理异步操作,JavaScript 引入了 Promise 和 async/await 语法。async/await 是基于 Promise 的语法糖,使得异步代码看起来更像同步代码,从而提高了代码的可读性和维护性。

1. Promise 回顾

在介绍 async/await 之前,我们先回顾一下 Promise 的基本概念。

1.1 Promise 的基本结构

Promise 是一个表示异步操作最终完成或失败的对象。它有三种状态:

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功!');
    }, 1000);
});

myPromise.then(result => {
    console.log(result); // 输出: 成功!
}).catch(error => {
    console.error(error);
});

1.2 Promise 链式调用

Promise 可以通过 .then() 和 .catch() 方法进行链式调用,使得异步操作的流程更加清晰。

fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('请求失败:', error));

2. Async/Await 语法

async/await 是 ES2017 引入的新特性,旨在简化异步代码的编写和阅读。

2.1 async 函数

async 函数是一个返回 Promise 的函数。在 async 函数内部,可以使用 await 关键字来等待一个 Promise 的解析。

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);
    }
}

fetchData();

2.2 await 关键字

await 关键字只能在 async 函数内部使用。它用于暂停函数的执行,直到 Promise 被解析或拒绝。

async function getData() {
    const promise = new Promise((resolve, reject) => {
        setTimeout(() => resolve('数据已加载'), 1000);
    });

    const result = await promise;
    console.log(result); // 输出: 数据已加载
}

getData();

3. 错误处理

在 async/await 中,错误处理通常使用 try/catch 块来捕获异步操作中的错误。

async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('请求失败:', error);
    }
}

fetchData();

4. 并行执行

如果多个异步操作可以并行执行,可以使用 Promise.all 来同时启动多个 Promise,并使用 await 等待它们全部完成。

async function fetchMultipleData() {
    try {
        const [data1, data2] = await Promise.all([
            fetch('https://api.example.com/data1').then(response => response.json()),
            fetch('https://api.example.com/data2').then(response => response.json())
        ]);

        console.log('数据1:', data1);
        console.log('数据2:', data2);
    } catch (error) {
        console.error('请求失败:', error);
    }
}

fetchMultipleData();

5. 实践练习

练习1: 模拟异步数据加载

编写一个 async 函数,模拟从两个不同的 API 加载数据,并输出结果。

async function loadData() {
    try {
        const [user, posts] = await Promise.all([
            fetch('https://jsonplaceholder.typicode.com/users/1').then(response => response.json()),
            fetch('https://jsonplaceholder.typicode.com/posts?userId=1').then(response => response.json())
        ]);

        console.log('用户信息:', user);
        console.log('用户帖子:', posts);
    } catch (error) {
        console.error('数据加载失败:', error);
    }
}

loadData();

练习2: 错误处理练习

编写一个 async 函数,尝试从无效的 URL 加载数据,并使用 try/catch 块捕获错误。

async function fetchInvalidData() {
    try {
        const response = await fetch('https://invalid-url.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('请求失败:', error);
    }
}

fetchInvalidData();

6. 总结

async/await 是处理异步操作的一种强大且简洁的方式。它使得异步代码的编写和阅读更加直观,结合 Promise 和 try/catch 块,可以有效地处理异步操作中的错误。通过本教程的学习,你应该能够熟练地使用 async/await 来编写和处理异步代码。

7. 进一步学习

  • 深入了解 Promise 的高级用法,如 Promise.race 和 Promise.any。
  • 学习如何在实际项目中使用 async/await 处理复杂的异步流程。
  • 探索 async/await 在 Node.js 和其他 JavaScript 框架中的应用。

希望本教程对你理解 async/await 有所帮助!继续加油,探索更多 JavaScript 的奇妙世界!