详细示例,讲解事件循环(Event Loop)机制,看这一篇就够了。

1.浏览器中的线程有以下几种:

  • js执行线程
  • GUI渲染线程
  • 事件监听线程
  • 计时器计时线程
  • 网络通信线程

2.如何理解js单线程?

之所以说js单线程,是因为它的执行引擎只有一个线程,并且不会在执行期间开启新的线程。而并非是指浏览器单线程。

3.js执行栈

js线程执行任务时,会创建js执行栈。同步任务直接推入执行栈中执行,异步任务推入事件队列中,注册回调函数。当执行栈空闲时,js会去事件队列中读取事件当初注册的回调函数,到执行栈中,并执行函数。

4.事件队列划分

  • 宏队列:script, settimeout,ajax请求,dom事件
  • 微队列:Promise.then、MutationObserver

当执行栈空闲时,js首先会将微队列中的所有微任务执行完,再去执行宏队列中的宏任务。

一轮循环是这样的:当js执行时,先执行宏任务,遇到微任务,则推入微队列,并注册回调函数。当所有宏任务执行完后,会读取微任务注册的回调函数到执行栈中执行。执行完后。继续下一轮循环

看下面这个示例:

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');
结果:
// one
// two
// three

分析:

  • 首先整段代码可以看做是宏任务

  • 当js执行时,遇到setTimeout,它是宏任务,则放入宏队列,等待本轮执行完后,在一轮循环中执行。然后遇到了promise的then,则被推入微队列。

  • 接着,打印one。好了,到此,本轮所有的宏任务已经执行完毕,但是,本次循环并未结束。

  • 然后,js去微队列中读取then注册的回调函数执行,打印two

  • 注意了!!!到此,本轮所有任务执行完毕,本次事件循环结束了。

  • 接着,开启下一轮循环,执行settimeout,打印three。所以,输出结果为:

one
two
three
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章