Event Loop of Javascript

  1. js是单线程的?与异步矛盾嘛?

不矛盾,因为js执行是单线程的,但是浏览器是多线程的。其中的异步是靠浏览器是开新的进程去执行的。其中是依靠libuv
其的单线程是:一个浏览器中只有一个js的执行线程,同一时刻也只有一个js文件在执行,其会阻塞其他任务的进行。

先写点东西,
浏览器是多线程的,一般会有以下几个常驻的线程在运行

  • GUI render thread
  • JS engine thread (也就是下文所说的主线程)
  • asnyc http request thread
  • setTimeout thread
  • Event target thread
  • Event loop thread 这个是浏览器的主线程,其是一个无限循环,永远处于接受处理的状态,并等待事件(如布局和绘制事件)发生,并进行处理。
    浏览器是事件驱动的(event driven),其的很多行为会创建异步事件,然后将其加入到任务队列中去。

当js在解析过程中,碰见一些异步情况,如Ajax,setTimeout.etc,会
一个chrome浏览器的一个tab page中有一个不断循环的线程,叫做Event loop。其贯穿页面的开启和关闭。还有相关若干的线程,如GUI render thread、JS engine thread 、setTimeout thread、Event target thread、async http request thread,其中GUI和js thread是相斥的,一个运行会阻塞别一个运行。然后因为js是单线程的,然后这个js engine thread 会调用一个子线程去运行js代码,然后其他的线程去忙别的事情。

单线程的js在解析代码的时候,会将demo以call stack 进行解析。在不断的解析过程中,碰见异步的情况,js去调用web的apis,这个时候,就是让浏览器中其他的线程去完成异步情况。当其他的线程完成异步情况之后,将这个完成情况(也就是通常所说的消息,也指向回调函数)插入任务队列。然后等到执行栈没有任务的时候,eventLoop会将任务队列的任务给推到执行栈中进行执行。
同时也解释了为什么setTimeout(function(){},0),也不能直接involve 回调函数。因为setTimeout是个异步过程。只有当call stack中的任务运行结束之后,才会在callback queue中去调用setTimeout的callback function。

eventLoop.png

reference
可视化js工作流程
reference

中文文档和blog真的有时候不行,浪费了我一天的时间去弄懂这些。看完英语的,一个小时就搞懂了。mmp。

Update 📌

原来不光有Event Loop,还有microTask,macroTask,在去真的了解Promise才发现的。
下图中的taskQueue就是macrotask。
其中macroTask和microTask是两种任务队列,在上文中,是大致介绍javascript Engine的流程,但是并没有对其中的task queue进行划分。相比而言,大家更熟悉的一个词是任务队列(task queue,其实就是macroTask),大家更熟悉的关于事件循环的机制说法大概是:主进程执行完了之后,每次从任务队列里取一个任务执行。但是promise出现之后,这个说法就不太准确了。
JavaScript引擎对这两种队列有不同的处理,简单的说就是引擎会把我们的所有任务分门别类,一部分归为macroTask,另外一部分归为microTask,下面是类别划分:

  • macroTask: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering,平时的script中的代码
  • microTask: process.nextTick, Promise, Object.observe, MutationObserver

我们所熟悉的定时器就属于macroTask,但是仅仅了解macroTask的机制还是不够的。
update:2018-8-25 其中在js中,对于macroTask和microTask的处理是不一样的,如下图

image.png

为此总结一句口诀:代码运行就是宏,遇见new Promise()就执行,then放microTask中后执行,process.nextTick()等microTask,看进入taskQueue顺序,毕竟是队列,先进先出,setTimeout最后来。
强烈推荐看这个
promise/A+规范
detailsOfEventLoop.png

reference
reference1
从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
理解事件循环二(macrotask和microtask)

nodejs construction

nodejs.png

带你领略Nodejs前世今生

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容