JavaScript核心之事件循环

基本概念

  1. 宿主环境javascript

    • JS所在的运行环境,通常为浏览器,但也有其它的宿主环境,例如:node;
    • 每一个宿主环境都会提供不一样的API供JS调用,如windowdocumentsetTimeout、脱离浏览器就不会有这些API。
  2. JS执行引擎:JS宿主环境中的一个功能模块,用于解析并执行JS代码。
  3. 浏览器中的功能模块:一个模块占用一个线程。java

    • JS执行引擎
    • 计时器
    • 网络请求
    • 页面渲染
    • 事件监听
> JS是单线程的缘由是浏览器只会开一个JS执行引擎
  1. 异步代码:同一个线程里面的代码都是同步执行的,只有新开一个线程才能执行异步代码,因此只有浏览器提供的setTimeout,promise等能够调用其它线程的API才能执行异步代码。

事件队列

用于存放执行栈清空后执行的异步代码,一般从计时器、网络请求、事件监听等其它线程中获取。node

事件循环

  1. JS代码只能在执行引擎中执行,每次执行一个函数都会将函数推入执行栈(具体内容能够查看文章:JavaScript核心之执行上下文);
  2. 代码执行过程当中遇到setTimeout等函数时,会调用宿主中的其它线程(计时器);
  3. 其它线程中的函数执行完成事后,如计时器计时完成后,会将回调函数加入事件队列;
  4. 待执行栈全部同步代码执行完,执行栈清空后,JS引擎回去事件队列中看看有没有要执行的代码,有的话就入栈执行。

图解:
微信截图_20200203115944.pngsegmentfault

举个例子:这里以setTimeout为例,其它异步方法都是同样的promise

setTimeout(function bar(){
    console.log('计时器回调执行');
}, 0)

function foo(){
    console.log('foo函数执行');
}

foo();
//执行过程伪代码:
1. 执行栈入栈setTimeout函数;
执行栈:[setTimeout]
计时线程:[]
事件队列:[]

2. 浏览器遇到其它线程API,通知对应线程执行代码,此时浏览器唤起的是计时器线程,将setTimeout方法推入计时器线程;
执行栈:[]
计时线程:[setTimeout]
事件队列:[]

3. 执行栈继续执行后续代码,入栈foo函数,同时,计时线程中的setTimeout在计时;
执行栈:[foo]
计时线程:[setTimeout]
事件队列:[]

4. 计时完毕,计时线程将setTime方法的回调函数推入事件队列,而后计时器线程中的setTimeout执行完毕被销毁;
执行栈:[foo]
计时线程:[]
事件队列:[bar]

5. 执行foo函数,打印'foo函数执行',foo执行完毕,foo函数出栈;
执行栈:[]
计时线程:[]
事件队列:[bar]

6. 执行栈没有可执行代码,会隔一段时间去事件队列中查看(事件轮询)一下有没有可执行代码,此时查看到有一个bar函数,将bar函数推入执行栈;
执行栈:[bar]
计时线程:[]
事件队列:[]

7. 执行bar函数,打印'计时器回调执行',bar执行完毕,bar函数出栈;
执行栈:[]
计时线程:[]
事件队列:[]

从上述例子能够看出:浏览器

  1. setTimeout的计时并不许确,计时完成后只是将回调函数推入事件队列,并非立刻执行,还要等执行栈清空后才会执行;
  2. 无论setTimeout的方法是否是写在最前面,计时时间有多短,都是在同步代码执行完毕后才会执行。

宏队列,微队列

事件队列又能够细分为宏队列和微队列,每次执行栈清空后会先执行微队列中的任务,再执行宏队列中的任务;微信

  • 宏队列任务:计时器、网络请求、dom事件
  • 微队列任务:Promise.thenmutationObserver

举个例子:网络

setTimeout(function(){
    console.log('计时完成'); //3. 最后执行宏任务中的队列
}, 0);

new Promise(function(resolve, reject){
    console.log('promise 代码执行'); //1. 先执行,这里的代码是同步的
    resolve();
}).then(function(){
    console.log('promise resolve'); //2. 执行栈空了以后,先执行微队列中的任务
})
无论宏任务中的代码写在哪里,都是在微任务执行后再执行。由于浏览器会在微队列清空后再去看宏队列。
相关文章
相关标签/搜索