js中的事件循环机制

70 阅读3分钟

前言

事件循环大家都是耳熟能详的,今天我们就来回顾下,我们都知道事件循环的根本原因是在于js是一个单线程语言。

在以往的面试中也许会碰到这样的面试题:

面试官:什么是双线程和单线程,js为什么是单线程的

一般来说,只有进程才会出现线程,一个进程至少是要包含一个线程的。单线程就是只有一个线程,而多线程是包含两个及以上的线程。

我们的js就是在运行时就是一个进程,同时他也是一个单线程,后台语言一般都是多线程的。

浏览器中一般是存在如下线程的:

1·JS引擎线程

作用:负责处理执行javascript脚本

2.UI渲染线程

作用:负责渲染浏览器界面,包括解析HTML、CSS、构建DOM树,render树,绘制等。

3.事件监听线程

作用:用来完成事件处理的,例如:click,mouseover…

4.计时器线程

作用:负责处理定时器。setInterval和setTimeout

5.网络线程

作用:负责处理http网络请求的

js设计成单线程的理由:

js主要是实现用户与浏览器的交互,以及操作dom;这决定了它只能是单线程,否则会带来很复杂的同步问题。 举个例子:如果js被设计了多线程,如果有一个线程要修改一个dom元素,另一个线程要删除这个dom元素,此时浏览器就会卡死,我他妈的到底是要干什么呢,,但是单线程就可以解决这个问题了,我只要通过事件循环就可以解决了,你不是修改吗,第一次改完了,那该轮到我删除了,咱俩轮换着来就行了。

js中的宏任务与微任务

js代码的执行也讲究个先来后到,举个例子,医院的缴费窗口,他就只有一个窗口,外面排起长队,到你了你就缴费就行了,有些人不行,他来到窗口墨迹半天,他说忘拿社保卡了没法看病优惠,没办法,那你就重新往后排队去吧

u=2197310207,2686354905&fm=253&fmt=auto&app=138&f=JPEG.webp

说白了js就是一个执行队列,队列中有人按照顺序有序进行,有人来回的在队列中排队,等待着去执行。

js中有两种任务队列:第一种是同步任务,第二种就是异步任务。

举个例子:

console.log("小小的花园里啊,挖呀挖呀挖");

setTimeout(()=>{
    console.log('美女荷官,在线发牌')
},1000)

Promise.resolve().then(()=>{
    console.log('一个人有两颗心,一个是贪心,一个是不甘心')
})

console.log("小小的花园里啊,挖呀挖呀挖"); -----------这就是同步任务

setTimeout(()=>{console.log('美女荷官,在线发牌')},1000)-----异步任务

Promise.resolve().then(()=>{ console.log('一个人有两颗心,一个是贪心,一个是不甘心') }) -------------异步任务

. 异步任务之宏任务和微任务

  • 宏任务:setTimeout、setInterval、setImmediate、script(整体代码)、 I/O 操作
  • 微任务:process.nextTick、promise.then()

20201129203145635.png

可以看出事件循环的本质如下:

js运行时,任务进入队列,先完成同步任务,后完成异步任务,而异步任务中先是完成微任务接着是完成宏任务。