JavaScript 异步编程:从回调到 Async/Await 进化

​作者简介:程序员转项目管理领域优质创作者

个人邮箱:[[email protected]]

PMP资料导航:PM菜鸟(查阅PMP大纲考点

座右铭:上善若水,水善利万物而不争。

绿泡泡:PM简读馆(包含更多PM常用免费资料)

        

目录

1. 回调函数(Callback)

2. Promise

3. Generator

4. Async/Await


JavaScript 异步编程:从回调到 Async/Await 进化_第1张图片

        在 JavaScript 中,异步编程是一个非常重要的概念,因为 JavaScript 是单线程的,异步操作可以避免阻塞主线程,从而提高程序的性能和响应能力。从早期的回调函数,到后来的 Promise、Generator,再到如今广泛使用的 Async/Await,异步编程的方式不断演进,变得越来越简洁和直观。下面将详细介绍从回调到 Async/Await 的演进过程。

1. 回调函数(Callback)

回调函数是 JavaScript 中最早用于处理异步操作的方式。在异步操作完成后,会调用预先定义好的回调函数来处理结果。

function fetchData(callback) {
    setTimeout(() => {
        const data = { message: 'Data fetched successfully' };
        callback(data);
    }, 1000);
}

fetchData((result) => {
    console.log(result.message);
});

缺点

  • 回调地狱(Callback Hell):当有多个异步操作需要依次执行时,会导致回调函数嵌套过深,代码变得难以阅读和维护。
    asyncOperation1((result1) => {
        asyncOperation2(result1, (result2) => {
            asyncOperation3(result2, (result3) => {
                // 更多嵌套...
            });
        });
    });

2. Promise

Promise 是 ES6 引入的一种异步编程解决方案,它可以避免回调地狱的问题。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { message: 'Data fetched successfully' };
            resolve(data);
        }, 1000);
    });
}

fetchData()
   .then((result) => {
        console.log(result.message);
    })
   .catch((error) => {
        console.error(error);
    });

优点

  • 链式调用:可以使用 .then() 方法链式调用多个异步操作,避免了回调地狱。
    asyncOperation1()
       .then((result1) => asyncOperation2(result1))
       .then((result2) => asyncOperation3(result2))
       .catch((error) => console.error(error));

3. Generator

Generator 是 ES6 引入的一种特殊的函数,它可以暂停和恢复执行。结合 Promise 和 Generator 可以实现异步编程的流程控制。

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { message: 'Data fetched successfully' };
            resolve(data);
        }, 1000);
    });
}

function run(gen) {
    const iterator = gen();

    function iterate(iteration) {
        if (iteration.done) return iteration.value;
        const promise = iteration.value;
        promise.then((result) => {
            return iterate(iterator.next(result));
        }).catch((error) => {
            return iterate(iterator.throw(error));
        });
    }

    return iterate(iterator.next());
}

function* main() {
    try {
        const result = yield fetchData();
        console.log(result.message);
    } catch (error) {
        console.error(error);
    }
}

run(main);

缺点

  • 代码复杂度较高:需要手动实现一个执行器来控制 Generator 的执行流程。

4. Async/Await

Async/Await 是 ES2017 引入的语法糖,它基于 Promise 实现,使得异步代码看起来更像同步代码,进一步简化了异步编程

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { message: 'Data fetched successfully' };
            resolve(data);
        }, 1000);
    });
}

async function main() {
    try {
        const result = await fetchData();
        console.log(result.message);
    } catch (error) {
        console.error(error);
    }
}

main();

优点

  • 代码简洁:使用 async 和 await 关键字,使得异步代码看起来更像同步代码,易于阅读和维护。
  • 错误处理方便:可以使用 try...catch 语句来捕获异步操作中的错误。

综上所述,从回调函数到 Async/Await 的演进,使得 JavaScript 异步编程变得越来越简洁、直观和易于维护。

你可能感兴趣的:(技术杂谈,javascript,开发语言,ecmascript)