一篇并不长的文章直接让你明白Event loop运行机制是什么

单线程的JavaScript

众所周知,我们的JavaScript是一种单线程语言,之所以是单线程,是由它的工作目的及用途来决定的:作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。如果JavaScript不是单线程语言就很容易造成一些冲突。比如,假定JavaScript同时有两个线程,一个线程是在某个DOM节点上添加内容,而另一个线程是删除了这个节点,这时浏览器应该以哪个线程为准?

那么问题来了,既然JavaScript是单线程语言的话,那它是如何实现一些异步操作的呢?

答案就是我们今天要讲的主题:JavaScript的事件循环

在讲事件循环之前,我们要先讲一些基础的知识点,方便同学们将整个事件循环更清楚,更深刻的串联起来。

浏览器

虽然JS引擎是单线程的,但是它的宿主环境(浏览器或node)却是多线程的,即浏览器内核中还有其他一些线程可以用来辅助JS引擎线程的执行。

下面列出一些浏览器的线程,同学们可以有个大概了解:

  1. GUI渲染引擎线程
  2. JS引擎线程
  3. 定时器触发线程
  4. 浏览器事件线程
  5. http异步线程
  6. ……

JS引擎线程

JS引擎线程,我们也可以称之为主线程,它的主要作用是运行JS同步代码,举例:

var a = 1          //1
console.log()     //2
setTimeout()     //3
ajax()          //4
复制代码

其中1,2行代码是同步代码,直接在主线程中执行,第3,4行代码是异步函数,被主线程分别分配给定时器触发线程和http异步线程这两个处理异步代码的线程进行执行

异步操作进程

我们前面提到的定时器触发线程,浏览器事件线程以及http异步线程等都是异步操作进程,这些进程主要是处理主线程分配的异步任务,这些被主线程扔过来的异步任务都会指定各自的回调函数当异步操作进程执行完任务之后,会将返回的回调函数发送给任务队列

任务队列

我们可以将任务队列看成是一个静态的队列存储结构(先进先出),这个存储结构中存放的是一些由异步操作进程扔过来的回调函数(是在异步任务完成之后,才将其回调函数扔在任务队列中。比如浏览器事件进程要处理一个点击事件,该事件有一个回调函数,是在点击事件完成之后,浏览器事件进程才将绑定的回调函数发送给任务队列)

Event loop

Event loop可以理解成一项任务或工作,主要作用是检测任务队列和主线程生成的执行栈,一旦执行栈中的代码执行完之后,就会自动从任务队列中抽取回调函数。

Event loop也可以理解成一种机制或运行模式,可以将:主线程分配异步任务给异步操作线程,异步操作线程执行任务完成后分配回调函数给任务队列,任务队列保存回调函数,然后当主线程执行完代码后会抽取任务队列中的回调函数。这一项循环称之为Event loop

每个人都有自己的理解方式和思维想法,不管怎么样理解记忆,我的这篇文章让同学们明白了Event loop怎么运行就好。

在我们的实际开发中也许并不需要理解Evnet loop对异步操作的影响,但在我们对其进行了一定程度上的学习和理解之后,我们会对一个包含异步操作的脚本/函数的执行有更加明确的认知,更加清楚它在执行中处于一个怎样的位置和状态

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享