一文了解事件循环

进程和线程

keywords: 程序运行所需要的专属内存空间叫做进程,在进程中运行代码的[人]叫做线程

程序运行所需要专属的内存空间,可以把这块内存空间简单的理解为进程

运行代码的「人」称之为「线程」。

一个进程至少有一个线程,所以在进程开启后会自动创建一个线程来运行代码,该线程称之为主线程。

浏览器有哪些进程和线程?

  1. 浏览器进程
  2. 网络进程:加载网络资源
  3. 渲染进程:渲染进程启动后,会开启一个渲染主线程,主线程负责执行 HTML、CSS、JS 代码。默认每个标签页都会有一个渲染进程

谈谈事件循环吧

keywords: 浏览器渲染主线程的工作方式

事件循环又叫做消息循环,是浏览器渲染主线程的工作方式

在 Chrome 的源码中,它开启一个不会结束的 for 循环,每次循环从消息队列中取出第一个任务执行,而其他线程只需要在合适的时候将任务加入到队列末尾即可。

过去把消息队列简单分为宏队列和微队列,这种说法目前已无法满足复杂的浏览器环境,取而代之的是一种更加灵活多变的处理方式。

根据 W3C 官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列不同类型的任务可以属于不同的队列。不同任务队列有不同的优先级,在一次事件循环中,由浏览器自行决定取哪一个队列的任务。但浏览器必须有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。

如何理解 JS 的异步?

keywords: 渲染主线程只有一个某些工作同步执行会导致阻塞

JS是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个。

渲染主线程承担着诸多的工作,如果都使用同步的方式,就极有可能导致主线程产生阻塞,所以浏览器采用异步的方式来避免

具体做法是当某些任务发生时,将任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。当其他线程完成时,将事先传递的回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行

常见宏任务

  1. 定时器任务:setTimeout/setInterval
  2. 页面渲染
  3. 事件回调 I/O操作
  4. 网络请求
  5. setImmediate()(node.js环境)

常见微任务

  1. Promise 回调函数
  2. Async/await
  3. MutationObsever 回调函数
  4. process.nextTick

浏览器事件循环的流程是什么?

  1. 每次循环都会检查消息队列中是否有任务。如果有,就拿出队列中的第一个任务执行,如果没有,则进入休眠状态
  2. 当其他线程把异步任务处理完成,就会将后续的回调操作包装成新任务,加入消息队列末尾,等待渲染主线程拿取执行。

其中,微任务消息队列优先级最高,浏览器渲染主线程会优先拿去,其次是其他消息队列

NodeJS 事件循环的流程是什么?

nodejs 中的异步代码会交给 libuv 执行,同步代码则在主线程中执行。

  1. timers 计时器队列:保存setTimeout,setInterval相关回调
  2. pending callback 阶段:调用上一次事件循环没在 poll 阶段立刻执行,而延迟的 I/O 回调函数
  3. idle,prepare 阶段:node内部使用
  4. poll轮询队列:处理除 timers 和 check 队列外的绝大多数 I/O 回调任务
  5. check检查队列:负责处理 setImmediate 定义的回调函数
  6. close callbacks: 执行所有注册 close 事件的回调函数

在上面过程中任意一个阶段遇到微任务则先清空微任务队列。

微任务队列包括:nextTick, Promise;

nextTick 优先级更高

setTimeout(() => { console.log('setTimeout'); }, 0) 

setImmediate(() => { console.log('setImmediate'); })

每次执行到 timers 队列时,定时器观察者内部会去检查代码中的定时器是否超过定时时间,而 setImmediate 则是直接将回调任务加入到 check 队列。

所以总的来说,setImmediate 的执行效率要远高于 setTimeout。所有上诉代码setTimeout不一定先于setImmediate加入队列,无法预测结果。

原文链接:https://juejin.cn/post/7350880189837164580 作者:xiyueyezibile

(0)
上一篇 2024年4月2日 下午4:18
下一篇 2024年4月2日 下午4:28

相关推荐

发表回复

登录后才能评论