ES6(11) async/await 详解

1. async/await 简介

async/await 是 ES8(ES2017)引入的用于处理异步操作的语法糖,使得异步代码更具可读性,避免了回调地狱(callback hell)Promise.then() 链式调用带来的嵌套问题。

1.1 async 关键字

  • async 用于定义一个异步函数

  • async 函数会默认返回一个 Promise

  • 函数内部可以使用 await 关键字来等待异步操作完成。

示例:

async function fetchData() {
    return "Hello, async!";
}
fetchData().then(console.log); // 输出:Hello, async!

1.2 await 关键字

  • await 只能在 async 函数内使用。

  • 它会暂停函数执行,直到 Promise 解析完成,然后继续执行代码。

  • await 返回 Promise 解析的结果。

示例:

async function fetchData() {
    let response = await Promise.resolve("Hello, await!");
    console.log(response);
}
fetchData(); // 输出:Hello, await!

2. async/await 替代回调地狱

2.1 回调地狱示例

如果使用回调函数处理多个异步任务,会造成代码嵌套过深,难以维护。

axios.get('http://127.0.0.1/get').then(response => {
    console.log("get.data:", response.data);
    if (response.data.data.web == "dengruicode.com") {
        return axios.get('http://127.0.0.1/article/get/id/1').then(response2 => {
            console.log("get2.data:", response2.data);
            if (response2.data.data.name == "theodore") {
                return axios.get('http://127.0.0.1/article/get/search/title/入门').then(response3 => {
                    console.log("get3.data:", response3.data);
                });
            }
        });
    }
}).catch(error => {
    console.log("get.error:", error);
}).finally(() => {
    console.log("get.finally");
});

2.2 使用 async/await 优化

async/await 让代码更加清晰,可读性更强。

const getData = async () => {
    try {
        // 发送 GET 请求
        const response = await axios.get('http://127.0.0.1/get');
        console.log("async.get.data:", response.data);

        if (response.data.data.web === "dengruicode.com") {
            const response2 = await axios.get('http://127.0.0.1/article/get/id/1');
            console.log("async.get2.data:", response2.data);

            if (response2.data.data.name === "theodore") {
                const response3 = await axios.get('http://127.0.0.1/article/get/search/title/入门');
                console.log("async.get3.data:", response3.data);
            }
        }
    } catch (error) {
        console.log("async.get.error:", error);
    } finally {
        console.log("async.get.finally");
    }
};

getData();

3. async/await 处理多个异步任务

3.1 await 串行执行

多个 await按顺序执行,后续任务必须等待前一个完成。

async function fetchData() {
    let res1 = await axios.get('http://127.0.0.1/api1');
    console.log(res1.data);
    let res2 = await axios.get('http://127.0.0.1/api2');
    console.log(res2.data);
}

3.2 Promise.all() 并行执行

如果多个异步操作互不依赖,可以使用 Promise.all() 并行执行,提高效率。

async function fetchData() {
    let [res1, res2] = await Promise.all([
        axios.get('http://127.0.0.1/api1'),
        axios.get('http://127.0.0.1/api2')
    ]);
    console.log(res1.data, res2.data);
}

4. 处理 await 超时或错误

4.1 处理超时

可以使用 Promise.race() 设置请求超时时间。

async function fetchData() {
    let timeout = new Promise((_, reject) => setTimeout(() => reject(new Error("请求超时")), 5000));
    try {
        let response = await Promise.race([axios.get('http://127.0.0.1/api'), timeout]);
        console.log(response.data);
    } catch (error) {
        console.error(error.message);
    }
}

4.2 使用 try...catch 捕获错误

如果 await 遇到错误,Promise 会进入 rejected 状态,建议使用 try...catch 处理异常。

async function fetchData() {
    try {
        let response = await axios.get('http://127.0.0.1/error');
        console.log(response.data);
    } catch (error) {
        console.error("请求失败:", error.message);
    }
}

5. async/await 与普通函数的结合

可以在普通函数中使用 async 定义的函数。

function normalFunction() {
    getData().then(() => console.log("执行完毕"));
}
normalFunction();

6. 结语

async/await 是对 Promise 的封装,使得异步代码更易读、更可维护。它的主要优势包括:

  • 消除回调地狱,避免嵌套过深。

  • 代码清晰易读,类似同步代码。

  • 错误处理更方便,可以使用 try...catch 捕获异常。

  • Promise.all() 结合,提高执行效率

掌握 async/await,可以让 JavaScript 的异步编程更加高效!

你可能感兴趣的:(ES6,javascript,前端,开发语言,ecmascript,es6)