当前位置: 首页 > news >正文

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

 🎬 江城开朗的豌豆:个人主页

 🔥 个人专栏 :《 VUE 》 《 javaScript 》

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

在这里插入图片描述

目录

📘 1. 引言

📘 2. 使用方法

📘 3. 实现原理

📘 4. 写到最后


 

📘 1. 引言

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

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

为了结合Promise和生成器的优势,Async/awaitECMAScript 2017(ES8)中被引入。它通过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

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

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

http://www.lryc.cn/news/186203.html

相关文章:

  • 前后端分离计算机毕设项目之基于SpringBoot的无人智慧超市管理系统的设计与实现《内含源码+文档+部署教程》
  • 从0开始python学习-31.selenium 文本输入框、下拉选择框、文件上传、时间插件选择元素定位
  • MyCat-web安装文档:安装Zookeeper、安装Mycat-web
  • Ajax跨域访问,访问成功但一直走error不走success的的问题解决
  • 水星 Mercury MIPC251C-4 网络摄像头 ONVIF 与 PTZ 云台控制
  • Reactor 模式网络服务器【I/O多路复用】(C++实现)
  • 2019年[海淀区赛 第2题] 阶乘
  • CMM—软件企业走向世界的通行证
  • 基于FPGA的图像形态学腐蚀算法实现,包括tb测试文件和MATLAB辅助验证
  • 华为云云耀云服务器L实例评测|RabbitMQ的Docker版本安装 + 延迟插件安装 QQ邮箱和阿里云短信验证码的主题模式发送
  • 解决Linux安装AppImage文件chrome-sandbox出错问题
  • Axios、SASS学习笔记
  • 开发工作中常用到的免费API分享
  • 外汇天眼:三大方法提高容错率——成功投资者的秘密策略!
  • 设计模式-状态模式
  • 支持多种格式照片处理软件Lightroom Classic 2022 mac中文功能特点
  • UML简介
  • 【PostgreSQL内核学习(十七)—— (AutoAnalyze)】
  • C++中指向成员的指针运算符(.* 和 ->*)用法说明
  • ASUS华硕ZenBook灵耀X逍遥UXF3000E_UX363EA原装出厂预装Win11系统工厂模式安装包
  • 【数据结构】栈和队列-- OJ
  • 访问Apache Tomcat的管理页面
  • 企业组织内如何避免山头文化?
  • 【c#】线程Monitor.Wait和Monitor.Pulse使用
  • GitLab平台安装中经典安装语句含义解析
  • 湘潭大学 2023年下学期《C语言》作业0x03-循环1 XTU OJ 1094,1095,1096,1112,1113
  • 【Linux系统满足产品实时性需求】
  • 不用休眠的 Kotlin 并发:深入对比 delay() 和 sleep()
  • 在Ubuntu中批量创建用户
  • 汽车冲压车间的RFID技术设计解决方案