-
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。
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的处理是不一样的,如下图
为此总结一句口诀:代码运行就是宏,遇见new Promise()就执行,then放microTask中后执行,process.nextTick()等microTask,看进入taskQueue顺序,毕竟是队列,先进先出,setTimeout最后来。
强烈推荐看这个
promise/A+规范
reference
reference1
从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
理解事件循环二(macrotask和microtask)
nodejs construction
带你领略Nodejs前世今生