Skip to content

Commit 42182e2

Browse files
committed
Update NodeJS.md
1 parent 6725979 commit 42182e2

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

面试相关/NodeJS.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,48 @@ HTTP2.0采用二进制传输数据,采用多路复用,压缩了报文头部
279279
* 使用QUIC作为传输协议:HTTP 3基于QUIC(Quick UDP Internet Connections)协议,取代了TCP作为传输层协议。
280280
* 改进的拥塞控制:HTTP 3使用了更先进的拥塞控制算法,提高了网络的稳定性和性能。
281281
* 减少握手延迟:QUIC协议通过0-RTT(零往返时间)握手和快速握手恢复,减少了握手的延迟。
282-
* 抗丢包能力:QUIC协议具有更好的丢包恢复能力,可以更快地恢复丢失的数据包。
282+
* 抗丢包能力:QUIC协议具有更好的丢包恢复能力,可以更快地恢复丢失的数据包。
283+
284+
# 事件循环最新
285+
宿主环境(浏览器或者NodeJS)中有一个主线程,大量的JavaScript事件在此发生,包括渲染、DOM存在,大部分的活动是顺序执行的
286+
287+
但是如果主线程上的任务需要很长时间,它会阻止网页的加载、渲染和交互
288+
289+
因此,虽然有主线程,还需要其他线程用来网络请求、IO等。这些线程如果执行完成或执行过程中需要页面响应,它们需要通知主线程。由事件循环来进行协调
290+
291+
比如setTimeout。肯定不能在主线程上等待,因此需要另外开启一个线程等待,但这样可能导致很多个线程同时修改DOM,引发竞争条件。因此需要创建一个任务队列,将setTimeout的回调方法添加到任务队列,以便在某个时刻回到主线程继续执行
292+
293+
所有的需要等待的请求,包括IO、网络请求、数据库操作,都只需要向任务队列中加入任务即可
294+
295+
没有任何事件时,事件循环只是在主线程上空转,以节省CPU的方式
296+
297+
当任务队列中的任务需要回到主线程执行时,事件循环会绕道经过任务队列来执行对应的任务
298+
299+
渲染内容是另一个队列,需要渲染时,事件循环会进入这个队列执行渲染
300+
301+
如果出现while(true),则相当于把主线程卡死在任务队列中,无法继续执行
302+
303+
## 微任务
304+
通常和promise联系起来,但这不是微任务的初衷。90年代时,浏览器想提供给开发者一种监控DOM变化的方法,于是有了DOM变化事件,即addEventListener。
305+
306+
但实践中发现,假设addEventListener监控新的DOM元素被插入,然后有一百个元素被for循环批量插入,并且设置文本内容,这样就会产生200个事件,大大拖慢性能。
307+
308+
我们想要对于这种批量操作只产生一个事件,希望浏览器暂时不处理,等一个合适的时间的来处理所有的变化。即只想被通知1次而不是200次。解决方案是使用DOM变化事件的观察者,它们创建了一个新队列就叫做**微任务队列**
309+
310+
微任务会在JavaScript执行堆栈(同步代码)全部结束后执行。因此监控元素插入事件会在插入100个元素(同步代码)全部执行完成后才执行
311+
312+
Promise也使用了微任务
313+
```js
314+
Promise.resolve().then(()=> console.log('Hey!'));
315+
console.log('Yo!');
316+
```
317+
先输出Yo!,再输出Hey!
318+
319+
## 宏任务和微任务的区别
320+
如果执行堆栈已经清空,接下来如果一直有新的微任务,则会一直执行,即使执行堆栈又有新的任务进来,也不会执行
321+
322+
但如果一直有新的宏任务,则浏览器会抽空完成执行堆栈中的任务
323+
324+
用户点击和JS click点击的效果可能不同
325+
326+

0 commit comments

Comments
 (0)