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

17 | 消息队列:V8是怎么实现回调函数的?

readFile的执行流程
readFileSync的执行流程
XMLHttpRequest触发的回调流程
setTimeout执行流程
任务执行流程
消息队列
异步回调
同步回调
思考题
异步回调函数的调用时机
UI线程的宏观架构
回调函数类型
V8执行回调函数

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

你好,我是李兵。
我们在使用 JavaScript 时,经常要用到大量的回调函数,比如在浏览器中可以使用 setTimeout 来设置定时器,使用 XMLHTTPRequest 来异步下载资源文件,在 Node 中可以使用 readFile 来读取文件,这些操作都有一个共同的特点,那就是需要给调用 API 传入回调函数,然后浏览器或者 Node 会将执行处理的结果通过回调函数来触发。
从内部了解回调函数,可以帮助我们梳理清楚很多问题:
有助于我们理解浏览器中的 Web API 到底是怎么工作的;
有助于我们理解宏任务和微任务到底有哪些区别;
理解回调函数,是理解异步编程模型 async/await 的基础。
这些内容在我们实际的项目中都会频繁使用到,所以理解 V8 是怎么实现回调函数的就显得至关重要了。

什么是回调函数?

那究竟什么是回调函数呢?其实回调函数也是个函数,就像白马也是马一样。它具有函数的所有特征,它可以有参数和返回值。如果单独给出一个函数,你是看不出来它是不是回调函数的。回调函数区别于普通函数,在于它的调用方式。只有当某个函数被作为参数,传递给另外一个函数,或者传递给宿主环境,然后该函数在函数内部或者在宿主环境中被调用,我们才称为回调函数。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

V8引擎是JavaScript的运行环境,本文深入探讨了V8是如何实现回调函数的。回调函数是JavaScript中常用的编程模式,通过setTimeout、XMLHTTPRequest等API实现异步操作。文章首先介绍了回调函数的概念和同步、异步回调的区别,然后详细解释了V8的线程架构模型和UI线程的工作原理。通过分析UI线程处理下载事件的流程,阐述了异步回调函数的调用时机。文章深入浅出地解释了V8引擎中回调函数的实现原理,对于理解JavaScript异步编程模型和V8引擎的工作原理具有重要意义。 总结:本文深入探讨了V8引擎中回调函数的实现原理,介绍了同步和异步回调函数的执行流程,以及UI线程的工作原理。通过分析setTimeout和XMLHTTPRequest的执行流程,读者可以更好地理解JavaScript中的异步编程模型和V8引擎的工作原理。 思考题:文章还提出了一个思考题,分析了Node中的readFileSync和readFile函数的执行流程,读者可以在留言区分享讨论。 这篇文章对于想深入了解JavaScript异步编程和V8引擎工作原理的读者来说,是一篇具有启发性的技术文章。

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

全部留言(32)

  • 最新
  • 精选
  • 洋洋
    readFileSync函数执行时会等待文件读取完毕,再执行下一条语句,在该语句后可正常访问其执行结果(获取data); readFile函数执行时不会等待文件读取完毕就会执行下一条语句,如果直接在其后而不是回调函数中操作其执行结果data时,程序会出现报错; 不知道理解有没有偏差,望老师指正!

    作者回复: 是的,本质是readFileSync是在主线程上执行的,readFile在读写线程中执行的

    2020-04-23
    4
    20
  • 董小聪
    老师,setTimeout的事件会立即被放进事件队列吗?我的理解是应该先放进一个类似于堆的数据结构然后等到指定的时间到后才放到事件队列的?

    作者回复: 不是这样的,在浏览器中这块比较复杂,实际上有另外一个队列用来存放定时器中的回掉事件的,然后还有一个任务调度器,它会从一系列的事件队列中,按照一定规则取出下一个要执行的事件,这个调度策略比较复杂,展开来讲就是一篇文章的内容了。 我觉得你把它看成黑盒就可以了。

    2020-04-23
    9
    12
  • -_-|||
    看文章感觉“UI 线程“就是“主线程“

    作者回复: 在浏览器中页面的UI线程就是主线程,在Node中主线程就是主线程 :)

    2020-07-01
    10
  • 非洲大地我最凶
    老师,请问这里的网络线程和网络进程有什么联系呢,文中所说1的网络线程指的是渲染进程里面的异步http请求线程吗

    作者回复: Chrome浏览器中比较复杂,下载的是采用了进程。 我在这里只是介绍一个通用的模型,一般都是采用线程的。 其实不管是线程还是进程,大的原理是一样的,都是丢给一个和主线程平行的线程或者进程来处理,处理过程中会动态返回结果给主线程!

    2020-04-23
    2
    8
  • 西门吹雪
    其实也是一样的疑问 settimeout是立即放入消息队列还是等时间到了再放入的?

    作者回复: 定时器有单独的队列,每次执行新的宏任务时,主线程会先在这两个队列中查找即将要执行的事件,然后执行

    2020-06-13
    4
    6
  • 不二
    首先要知道浏览器早期的线程机制: 早期其实只有一个ui线程,js的执行也是在ui线程中,那么,鼠标的各种事件,例如鼠标移动事件,每移动一像素就会触发一次事件,很显然,ui线程是无法及时响应和处理这些事件的,所以 “消息队列”的出现就是为了解决这个问题的。 消息队列:即把没执行的事件全部放到了一个队列中,然后ui线程不断轮训这个队列,然后取出新的事件执行,直到队列为空,当前ui线程也会被挂起。 settimeout: 遇到定时器,浏览器会将定时器的回调函数封装成一个事件,进入消息队列,然后在合适的时间点从消息队列中取出该事件,并且执行回调函数。 xmlHttpRequest: 遇到ajax请求时,即执行xmlHttpRequest.send()时, ui线程会将该请求任务转发给网络线程,然后send函数推出,ui线程继续执行,网络线程执行该请求任务,然后将返回的数据和回调函数封装成一个新的事件,并添加到消息队列中。然后ui线程从消息队列中取出事件,并且执行回调函数。

    作者回复: 很赞

    2020-05-26
    4
  • Miracle
    老师我有个问题,UI线程就是渲染进程里的主线程,那么消息队列里的是 XMLHttpRequest的话,是交给网络进程里的一个网络线程,还是在这个渲染进程里面有一个网络线程?

    作者回复: 在目前的Chrome浏览器里面是交给网络进程里面的一个线程来处理的

    2020-04-26
    4
  • 蔡孟泳
    有个歧义点,UI线程和主线程,UI 线程提供一个消息队列,并将待执行的事件添加到消息队列中,然后 UI 线程会不断循环地从消息队列中取出事件、执行事件,而对于setTimeout,在时间到了之后,任务被进入消息队列,那这时候文中说是主线程来执行时间。 所以,执行消息队列中的事件是UI线程还是主线程,亦或是主线程即UI线程,感觉文中有点混淆

    作者回复: 其实就是一个线程

    2020-04-23
    1
  • 西门吹雪
    感谢很有收获

    作者回复: :)

    2020-06-13
  • Geek_177f82
    老师举的例子是早期单进程浏览器架构,那能否补充下多进程架构以及soa(尤其是这个架构,目前chrome已经采用这个架构了。)架构的例子。

    作者回复: 目前chrome正在往这个架构迭代,老架构和新架构并存的状态

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