全栈工程师修炼指南
熊燚(四火)
Oracle 首席软件工程师
32206 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 46 讲
全栈回顾 (1讲)
加餐 (1讲)
全栈工程师修炼指南
15
15
1.0x
00:00/00:00
登录|注册

19 | 打开潘多拉盒子:JavaScript异步编程

catch 方法
reject 回调
function* 和 yield 关键字
迭代器协议
可迭代协议
协作式多任务的子程序
使用 async/await
使用 Promise.resolve()
resolve 和 reject 参数
构造方法
金字塔厄运
嵌套回调
异步编程的进一步学习
ES6 新特性
MDN 的 Promise 文档
ES6 和 ES7 的高级特性和语法糖
JavaScript 异步编程的技术应用
async/await 下的异常处理
Promise 的异常处理
生成器实现协程
生成器
协程
优化嵌套回调
Promise
异步编程问题
异步编程概念
事件驱动模型
扩展阅读
总结思考
异步错误处理
用生成器来实现协程
用 Promise 优化嵌套回调
异步编程
JavaScript 异步编程

该思维导图由 AI 生成,仅供参考

你好,我是四火。
我们在本章伊始的 [第 14 讲] 中初步学习了 JavaScript 的事件驱动模型,体会到了思维模式的转变,也建立起了异步编程的初步概念。在本章最后一讲,我们将深入异步编程,继续探讨其中的关键技术。
异步编程就像是一个神秘的宝盒,看起来晶莹剔透,可一旦使用不当,就会是带来灾难的潘多拉盒子,状态混乱,难以维护。希望在这一讲之后,你可以了解更多的关于 JavaScript 在异步编程方面的高级特性,从而习惯并写出可靠的异步代码。

1. 用 Promise 优化嵌套回调

假如我们需要写这样一段代码,来模拟一只小狗向前奔跑,它一共跑了 3 次,奔跑的距离分别为 1、2、3,每次奔跑都要花费 1 秒钟时间:
setTimeout(
() => {
console.log(1);
setTimeout(
() => {
console.log(2);
setTimeout(
() => {
console.log(3);
},
1000
);
},
1000
);
},
1000
);
你看,我们用了 3 次 setTimeout,每次都接受两个参数,第一个参数是一个函数,用以打印当前跑的距离,以及递归调用奔跑逻辑,第二个参数用于模拟奔跑耗时 1000 毫秒。这个问题其实代表了实际编程中一类很常见的 JavaScript 异步编程问题。例如,使用 Ajax 方式异步获取一个请求,在得到返回的结果后,再执行另一个 Ajax 操作。
现在,请你打开 Chrome 开发者工具中的控制台,运行一下:
3693
1
2
3
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

JavaScript异步编程是一个重要的话题,本文从嵌套回调的问题出发,介绍了使用Promise优化异步编程的方法。文章首先通过一个模拟小狗奔跑的例子展示了嵌套回调的问题,然后引入了Promise,通过then方法实现了清晰的链式调用,避免了嵌套回调的问题。接着介绍了使用async/await语法糖进一步简化异步代码的方法,使得异步编程更接近同步编程的表达方式。通过这些例子,读者可以了解到Promise和async/await的使用方法,以及如何优化异步编程,使得代码更加清晰易懂。整体来说,本文通过实际例子生动地展示了JavaScript异步编程的问题和解决方法,对于想要深入了解JavaScript异步编程的读者具有很好的参考价值。 文章还介绍了使用生成器来实现JavaScript协程的方法,通过生成器对象和yield关键字的配合,实现了协作式的挂起和恢复操作,从而在外部函数和生成器内部逻辑之间跳转,避免了线程切换的开销,具有资源开销更小的优势。最后,文章讨论了异步错误处理的问题,介绍了Promise的异常处理和async/await下的异常处理方法,使得读者能够更好地处理异步代码中可能发生的异常情况。整体来看,本文内容丰富,涵盖了JavaScript异步编程的优化方法以及协程的实现原理,对于想要深入了解JavaScript异步编程和错误处理的读者具有很好的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《全栈工程师修炼指南》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • Kevin·程
    开始没明白老师提出来javascript异步编程和前边的代码是要解决什么样的问题,而且promise也是看的一头雾水。后来反复研究一下,发现小狗跑步如果用顺序代码执行,但是每一步延迟时间不同的话,实现最终效果却未必是顺序的,甚至是相反的,如下代码: setTimeout(() =>{ console.log(1); } , 10000); //第一次跑10秒 setTimeout(() =>{ console.log(2); } , 8000); //第二次跑8秒 setTimeout(() =>{ console.log(3); } , 5000); //第三次跑5秒 结果是:3 2 1的顺序。 但是通过本文的代码实现方式,却是能够实现小狗1->2->3的顺序跑步过程的展现,避免上面代码导致的额不同步现象。本文代码稍加修改,好像更能体现这种同步控制的效果,如下: setTimeout( () => { console.log(1); setTimeout( () => { console.log(2); setTimeout( () => { console.log(3); }, 5000 ); }, 8000 ); }, 10000 ); 结果才是实际想要达到的1 2 3的顺序。因此个人理解这样是为了实现小狗跑步整个过程的同步控制。不知理解的对不对。

    作者回复: 我的这些例子,主要目的是为了示例原理和用法,帮助你更好理解异步编程。当然,有很多的实际业务场景,需要我们使用异步编程的方式来实现

    2020-04-19
    1
  • pyhhou
    1. Promise 以及 async/await 在目前开发的项目中均有用到,async/await 非常好用,用同步的风格写异步的代码,让代码清晰易懂,但是并不建议任何地方都加上 async/await,这会失去 JavaScript 异步的优势,比如说相互没有关联性的 I/O 处理,可以考虑使用 Promise.all(),另外建议尽量不要在循环里面写 async/await 进行 I/O 请求,这会严重影响程序运行效率 2. 个人不敢苟同。不得不承认 JavaScript 是一门有设计缺陷的语言,在其诞生之初仅仅是为了解决简单的问题,并没有什么宏伟的目标和规划,但是随着 Web 的迅速发展,JavaScript 的应用领域越来越广泛,从前端页面到后端的 Node,JavaScript 逐渐吸收其他语言的设计思想并结合自身情况进行重新设计,让其编写更自然也更高效。其实并不认同 “给编程人员的阅读和理解造成困扰”,像 Promise 的出现本身就是为了解决异步编码风格的问题,而不是其他问题,也许这会对那些只会 JavaScript,并且只会用 JavaScript 写简单的前端页面的人有困扰,但是对大多数程序员来说是好事。另外说到学习曲线,JavaScript 现在在前后端上都可以进行开发,难道说传统的后端语言,比如,Java、C++ 就没有学习曲线吗?应用领域变广泛,技术变多,学习曲线递增其实是再正常不过的事情,不过,到头来,还是像老师说的那样,技术都是相通的,理解其背后的思想是关键

    作者回复: 👍

    2019-11-05
    1
  • 李威
    好难懂啊

    作者回复: 老实说,这可能是这个专栏里面最难的两、三篇文章之一了。 要是有些内容你始终搞不懂,并且把具体问题讲出来的话,可以讨论

    2019-11-02
    1
  • 咕叽咕叽
    1,主要使用过如下的异步编程:使用过利用异步编程,将大的计算任务分成小的计算任务。当时的场景是页面滚动的同时,需要大量计算,某些手机会卡顿。将计算分成小的异步任务,可以保证滚动的流畅 2,个人不是很认同这种看法。写起来简单得js语法,可能阅读,维护比较困难,毕竟代码主要是给人看的。就如本文用Promise / async,await改善之前的嵌套写法,代码更优雅。

    作者回复: 👍

    2019-10-29
    1
  • 靠人品去赢
    这个promise“异步”变“同步”,就是让异步代码看起来像同步一样,刚看第一遍没看明白,还有就是箭头函数,箭头多了,我就不能第一时间看明白,看来还是用得少。

    作者回复: 用得少是一个方面,本来 JavaScript 如果书写的时候不注意结构和组织的话,确实容易写出难懂的代码

    2019-10-25
  • tt
    老师,JavaScript和Python确实太像了,尤其是异步函数、生成器以及协程的部分。 那么,对于小规模的团队,JavaScript+Python或者JavaScript+node.js的组合是不是比JavaScript+java在开发速度上更有优势呢?

    作者回复: 这个问题不太好回答,我也没有足够的统计数据。据我个人的经历,Python 开发效率确实是要比 Java 高出不少

    2019-10-23
  • 二狗
    异步 各种箭头嵌套 js好难读 好难懂
    2019-11-06
    1
    4
  • 第一装甲集群司令克莱斯特
    js的箭头代码,回调地狱 .
    2023-01-07归属地:北京
  • 零维
    老师,如何使用 promise 和 generator 模拟出 await 的返回值呢? 如果用 async/awiat: const res = await ajax(); 变成 yield 是: const res = yield ajaxWrap(); res 是怎么用 ajaxWrap 里面出来的呢?
    2019-10-28
    2
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部