图解 Google V8
李兵
前盛大创新院高级研究员
26763 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 25 讲
图解 Google V8
15
15
1.0x
00:00/00:00
登录|注册

19|异步编程(二):V8是如何实现async/await的?

co的运行原理
运行原理
await关键字
async函数
Promise和生成器应用
同步代码实现异步访问资源
ES7改进
协程
暂停和恢复函数执行
实现线性化逻辑
代码改造示例
fetch使用Promise
async/await解决方案
Generator函数解决方案
Promise解决方案
影响
async/await
Generator函数
Promise
思考题
async/await
Generator函数
Promise
回调地狱问题
解决方案
回调地狱问题
JavaScript单线程设计
异步编程

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

你好,我是李兵。
上一节我们介绍了 JavaScript 是基于单线程设计的,最终造成了 JavaScript 中出现大量回调的场景。当 JavaScript 中有大量的异步操作时,会降低代码的可读性, 其中最容易造成的就是回调地狱的问题。
JavaScript 社区探索并推出了一系列的方案,从“Promise 加 then”到“generator 加 co”方案,再到最近推出“终极”的 async/await 方案,完美地解决了回调地狱所造成的问题。
今天我们就来分析下回调地狱问题是如何被一步步解决的,在这个过程中,你也就理解了 V8 实现 async/await 的机制。

什么是回调地狱?

我们先来看什么是回调地狱。
假设你们老板给了你一个小需求,要求你从网络获取某个用户的用户名,获取用户名称的步骤是先通过一个 id_url 来获取用户 ID,然后再使用获取到的用户 ID 作为另外一个 name_url 的参数,以获取用户名。
我做了两个 DEMO URL,如下所示:
const id_url = 'https://raw.githubusercontent.com/binaryacademy/geektime-v8/master/id'
const name_url = 'https://raw.githubusercontent.com/binaryacademy/geektime-v8/master/name'
那么你会怎么实现这个小小的需求呢?
其中最容易想到的方案是使用 XMLHttpRequest,并按照前后顺序异步请求这两个 URL。具体地讲,你可以先定义一个 GetUrlContent 函数,这个函数负责封装 XMLHttpRequest 来下载 URL 文件内容,由于下载过程是异步执行的,所以需要通过回调函数来触发返回结果。那么我们需要给 GetUrlContent 传递一个回调函数 result_callback,来触发异步下载的结果。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

V8引擎是如何实现async/await的? JavaScript的单线程设计导致了回调地狱问题,为了解决这一问题,JavaScript社区提出了一系列方案,从Promise到Generator,再到最近的async/await。本文介绍了Promise和Generator函数的使用,以及V8是如何实现async/await的机制。通过对Promise和Generator函数的使用,以及协程的工作原理的解释,读者可以理解async/await的实现原理。文章通过代码示例和图表,生动地展示了这些概念的运作方式,帮助读者更好地理解JavaScript中异步编程的发展和V8的实现机制。 文章详细介绍了async/await的工作原理,以及V8引擎是如何处理await后面的内容的。通过对Promise对象的状态变化和协程的应用进行解释,读者可以清晰地理解async/await的实现机制。此外,文章还对异步编程模型的发展历程进行了梳理,从回调地狱问题到Promise和Generator函数的应用,最终演化到async/await的“终极”方案。 总的来说,本文通过深入浅出的方式,帮助读者理解了JavaScript中异步编程的发展历程以及V8引擎是如何实现async/await的机制。读者可以通过本文了解到async/await的演化过程,以及其与co+generator的比较优秀的设计,从而对前端异步编程的方案史有更清晰的认识。 通过本文的阅读,读者可以更好地理解JavaScript中异步编程的发展历程,以及async/await的实现原理,为他们在实际开发中更好地应用这些技术提供了重要的参考和指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《图解 Google V8》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • 若川
    置顶
    co源码实现原理:其实就是通过不断的调用generator函数的next()函数,来达到自动执行generator函数的效果(类似async、await函数的自动自行)。 具体代码分析,我之前写过一篇文章: 《学习 koa 源码的整体架构,浅析koa洋葱模型原理和co原理》 https://juejin.im/entry/5e6a080af265da575b1bd160

    作者回复: 赞,高手

    2020-05-02
    6
    44
  • HoSalt
    老师 async、await 是 generator promise 的语法糖吗,v8里面前者是借助后者实现的吗?async await 为什么能用try catch 捕获错误?

    作者回复: async/await可以不是语法糖,而是从设计到开发都是一套完整的体系,只不过使用了协程和promise! 支持try catch也是引擎的底层来实现的

    2020-04-29
    11
  • Geek_gaoqin
    哦,我知道了,async 修饰的函数会有自己的协程,那么它代码内部创建的宏任务,主线程有空了还是会拿消息队列中的宏任务来执行,如果await等待了一个never resolve,那么它后面的代码就再也不会执行!但是却不会影响消息队列中键盘鼠标事件等其它任务的执行!

    作者回复: 是这样的

    2020-06-11
    9
  • 潇潇雨歇
    co的原理是自动识别生成器代码的yield,做暂停执行和恢复执行的操作

    作者回复: 没问题

    2020-04-28
    7
  • 蹦哒
    请教老师:为什么Generator方案不实现自动执行next的功能呢?我理解async/await相对于Generator方案主要是能够自动执行next吧,co方案也是这么做的

    作者回复: 如果自动执行了,那么就是await了,之所以没有这样实现,我想是因为技术在迭代发展吧,完美的技术总是很难一步到位

    2020-05-12
    5
    5
  • Geek_gaoqin
    老师,很长很长一段代码中,业务逻辑很复杂,既有产生微任务,又有setTimeout产生宏任务,更有很多await的语句,那么这些结合上一章节讲的内容,它的执行顺序是怎样的呢?可以帮我分析下吗?

    作者回复: 微任务先执行,settimeout后执行,await可以跨越多个宏任务

    2020-06-11
    1
  • 华仔
    setTimeout(() => { console.log('in timeout'); }) new Promise((resolve, reject) => { setTimeout(() => { resolve(3); console.log('in promise-timeout') }) console.log('in promise') }).then((res) => { console.log('in then') }) 老师,想问下promise创建的then是微任务,是宏任务中创建的队列保存的消息队列中维护的。那么我这里这样一个场景,在promise中通过setTimeout(模拟宏任务http request)异步resolve的场景下,then也就会在下一个宏任务执行之后再执行了。这种当前宏任务中注册的微任务被拖到下一个宏任务执行,是怎么实现的呢?

    作者回复: 微任务是在reslove时生成的,你创建一个peomise并不会立马产生一个微任务,而是要等到resolve或者reject时,才会触发微任务,在那个宏任务中触发了微任务,微任务就在该宏任务快要执行结束之后执行,无论你promise是在拿个宏任务中创建的!

    2020-05-05
    4
    1
  • 断线人偶
    老师可以讲一下为什么在使用async...await...可以通过try...catch...来捕获到异步函数中的异常吗,v8是怎么实现的

    作者回复: 这个是V8实现的,比如触发了reject的时候,v8就会跳转到catch

    2020-05-24
  • 地球外地人
    老师能讲讲 generate 和 await async中的闭包吗?

    作者回复: 闭包的实现原理都是一样的,你可以列出具体问题,我来给你回答,最好新开一个回复,这样我更容易看到

    2020-05-04
  • 天然呆
    function HaveResolvePromise(){ return new Promise((resolve, reject) => { setTimeout(() => { resolve(100) }, 0); }) } async function getResult() { console.log(1) let a = await NoResolvePromise() console.log(a) console.log(2) } console.log(0) getResult() console.log(3) 是不是要改动?NoResolvePromise ==>> HaveResolvePromise

    作者回复: 嗯 改过来了

    2020-04-28
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部