V8引擎详解(八)——消息队列

前言

本文是V8引擎详解系列的第八篇,重点内容是关于V8引擎的消息队列,会经过单线程的特色入手来学习,逐步其消息队列的运行机制。
文末会有已经完成的系列文章的连接,本系列文章还在不断更新欢迎持续关注。javascript

单线程

为何是单线程

因为javascript最初做为浏览器脚本语言,主要用来与用户互动、操做dom等,若是有多个线程同时操做一个DOM的状况,会致使很是难以处理,因此javascript只能设计成单线程。前端

不过现代计算机基本都是多核CPU的,纯粹的单线程会致使一些性能得不到释放,因此新的 HTML5 标准中提出了 web worker概念,容许用户额外开启线程,不过 worker 线程是彻底受主线程控制(大部分状况处理一些计算逻辑),且没有操做DOM的权限,本质上javascript仍是单线程。java

异步任务

javascript只有一个主线程用来执行任务,可是同一时间只能执行一个任务也就是函数,普通的函数会造成一个任务队列排队执行,可是有些任务会很是耗时且不可控(网络请求、事件监听)等,若是让这些任务也和普通任务同样排队执行,那么执行效率低不说还会致使页面的卡死。
因而就有了异步任务,而 V8 引擎 经过消息队列事件循环 系统让异步任务执行且不用排队等待执行完毕。web

消息队列

消息队列是 V8引擎 除了主线程任务外,额外维护的一个队列,主要存放要执行的任务(函数)。彻底符合队列 先进先出 的特色,从队列的头部取出任务,从队列的尾部添加任务。面试

浏览器自己须要异步的场景很是多,而每一种异步操做的机制也各不相同, 消息队列能够和多种异步场景产生交互。ajax

  • 输入事件相关的异步交互(好比onClick)由引擎的 DOM Binding 模块处理,相应的事件触发时,会将对应的回调函数添加到消息队列中。
  • ajax请求相关的异步交互 由引擎的network模块处理,在网络请求完成返回以后,会将对应的回调函数添加到消息队列中。
  • 定时器相关的异步交互 会引擎的 timer 模块处理,当时间到达的时候,会将回调函数添加到任务队列中。(定时器调度策略比较复杂,会有专门的调度策略在合适的时间添加对应的回调任务)

以及一些其余的模块会将异步操做放置到消息队列中,在引擎主线程的任务都执行完成后再执行消息队列中被推送的任务。
具体以下图:vim

(图片来源: 《Help, I'm stuck in an event-loop》

那么消息队列会在何时执行呢?
每次执行栈中的代码就是一个宏任务(task),而消息队列中的任务会按顺序放到下一次的宏任务(task)中,每一个宏任务(task)在执行时,V8 都会从新建立栈,而后随着宏任务(task)中函数调用,栈也随之变化,最终,当该宏任务(task)执行结束时,整个栈又会被清空,接着主线程继续执行下一个宏任务(task)promise

而浏览器会在一个 宏任务(task) 执行结束后,在下一个 task 执行开始前,对页面进行从新渲染如图:浏览器

因为主线程执行消息队列中宏任务的时间颗粒度太粗了(主要中间有一次渲染过程),没法胜任一些对精度和实时性要求较高的场景,因此又引入了promise 机制也就是微任务如图:缓存

(本篇的重点不在于宏任务和微任务因此简单带过,可是我想表达的是,如今前端面试大几率都会问到宏任务和微任务,不少人都只会回答到宏任务和微任务的执行顺序,可是若是你回答出中间还有一个页面渲染的过程,才算真正了解)

事件循环

若是你能理解上文的消息队列机制,那么事件循环就很好理解了,本质上就是

  • 主线程运行产生了执行栈,在调用执行栈的过程当中调用了一些异步函数。
  • 当知足异步函数的触发条件时,会将对应的回调函数推送到消息队列中。
  • 当主栈中的代码执行完毕时,会触发一次页面渲染,而后建立新的主栈。
  • 将消息队列中的回调函数推送到主栈。而后顺序执行主栈的任务。
  • 反复循环执行上述过程就是时间循环。

总结

本文主要了解了关于V8引擎的消息队列的运行机制,也简单的了解了一下为何js使用单线程机制,以及简单说了一下宏任务和微任务(网上相关的好文章很是多,因此本文就不重复赘述,只是简单的点了一下容易被忽略的点)。若是有什么错误,请在评论中和做者一块儿讨论,若是您以为本文对您有帮助请帮忙点个赞,感激涕零。

参考文章

vimeo.com/96425312 time.geekbang.org/column/arti…

系列文章

V8引擎详解(一)——概述
V8引擎详解(二)——AST
V8引擎详解(三)——从字节码看V8的演变
V8引擎详解(四)——字节码是如何执行的
V8引擎详解(五)——内联缓存
V8引擎详解(六)——内存结构
V8引擎详解(七)——垃圾回收机制
V8引擎详解(八)——消息队列
V8引擎详解(九)——协程&生成器函数

相关文章
相关标签/搜索