一盏茶的功夫帮你彻底搞懂JavaScript异步编程从回调地狱到async/await

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

  江城开朗的豌豆个人主页

  个人专栏 :《 VUE 》 《 javaScript 》

⛺️ 生活的理想就是为了理想的生活 !

在这里插入图片描述

目录

1. 引言

2. 使用方法

 3. 实现原理

4. 写到最后


 

1. 引言

在深入讨论 async/await 之前我们需要了解一下 JavaScript 的单线程和非阻塞的特性。JavaScript 是单线程的也就是说在任何给定的时间点只能执行一个操作。然而对于需要大量时间的操作例如从服务器获取数据如果没有适当的管理机制这种单线程特性可能会导致应用程序的阻塞。为了解决这个问题JavaScript 引入了回调函数和后来的 Promise用来管理这些异步操作。

然而回调函数Promise 还是存在一些问题。回调函数很容易导致 "回调地狱"因为每个异步操作都需要一个回调函数如果有很多这样的操作代码就会变得非常混乱。Promise 解决了这个问题让异步代码更加直观但是Promise 的链式调用有时候还是显得不够直观。

为了结合Promise和生成器的优势Async/awaitECMAScript 2017ES8中被引入。它通过async函数和await表达式提供了一种更加直观和简洁的方式来编写异步代码消除了回调函数和手动管理Promise的需要。

2. 使用方法

Async/await的使用方法非常简单明了主要涉及两个关键字async和await。

  • async关键字用于声明一个async函数它返回一个Promise对象。在async函数内部我们可以使用await关键字来暂停函数的执行等待一个异步操作的完成并获得其结果。在这个过程中async函数会暂时释放线程的控制权使其他代码可以继续执行。

  • await关键字用于暂停async函数的执行等待一个Promise对象的完成并返回其解析的值。它只能在async函数内部使用。当使用await表达式时代码的执行会暂停直到Promise对象被解析或拒绝。

下面是一个示例展示了Async/await的使用方法

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

getData()
  .then(data => console.log('Data:', data))
  .catch(error => console.error('Error:', error));

在上面的示例中getData函数是一个async函数它等待fetch函数返回的Promise对象并使用await关键字获取响应的数据。最后我们使用.then方法处理返回的数据或使用.catch方法处理可能发生的错误。

 3. 实现原理

Async/Await 的实现原理其实就是 Generator + Promise。我们知道 Generator 可以在 yield 关键字处暂停和恢复执行Promise 可以处理异步操作两者结合在一起就可以实现一个类似于 async/await 的功能。


function promiseFn() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('promise resolved');
        }, 2000);
    });
}
function* genFn() {
    let result = yield promiseFn();
    console.log(result);
}
function asyncToGenerator(generator) {
    let gen = generator();
    return new Promise((resolve, reject) => {
        function step(key, arg) {
            let result;
            try {
                result = gen[key](arg);
            } catch (error) {
                return reject(error);
            }
            const { value, done } = result;
            if (done) {
                return resolve(value);
            } else {
                return Promise.resolve(value).then(val => {
                    step('next', val);
                }, err => {
                    step('throw', err);
                });
            }
        }
        step('next');
    });
}
asyncToGenerator(genFn);

在上述代码中我们首先创建了一个 promiseFn 函数该函数返回一个在 2 秒后解析的 Promise。然后我们创建了一个 Generator 函数 genFn在该函数内部我们使用 yield 关键字暂停执行并等待 promiseFn 的结果。最后我们创建了一个 asyncToGenerator 函数该函数接受一个 Generator 函数作为参数并返回一个新的 Promise这个 Promise 的解析值就是 Generator 函数的返回值。

4. 写到最后

总的来说Async/await是一种使得JavaScript异步编程变得更加友好和易用的语法特性。它帮助开发者以一种更加清晰和简洁的方式处理异步操作提升了代码的可读性和维护性。对于那些曾经苦于回调地狱的开发者来说Async/await是一种令人期待的改变它让我们可以更加舒心地编写异步代码。

请大家不吝赐教,在下方评论或者私信我,十分感谢.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

最后感谢各位的耐心观看既然都到这了点个 赞再走吧

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: JavaScriptJava