我们一起对 Node.Js 一问一答

开发 前端
在前端的时候,我们经常会轮询接口或定时去做一些事情,但是我们一般不使用 setInterval,因为浏览器中, setInterval 是用单独的线程实现的,当任务超市时,定时线程就会往 JS 线程追加一个回调任务。

[[428450]]

本文转载自微信公众号「编程杂技」,作者theanarkh。转载本文请联系编程杂技公众号。

一问一答是以问答的形式聊一下 Node.js 的一个个知识点。

1 setTimeout 和 setImmediate

setTimeout(() => {}, 0) 和 setImmediate 谁先执行,这个是 Node.js 里经常会被提到的一个问题,其实这两没什么关系,setImmediate 是 Node.js check 阶段的任务,setTimeout 是 timer 阶段的任务,在 Node.js 事件循环中,timer 阶段是在 check 阶段执行的,看起来 setTimeout 的回调肯定比 setImmediate 的回调先执行,但是 Node.js 的实现中规定了 setTimeout 的超时时间最小是 1,这就导致了事件循环开始时,定时器可能到期也可能不到期的情况,所以谁先执行是不一定的。下面是示例代码。

  1. setTimeout(() => { 
  2.     console.log('setTimeout'
  3. }, 0); 
  4.  
  5. setImmediate(() => { 
  6.     console.log('setImmediate'
  7. }); 

2 浏览器和 Node.js 的 setInterval 有什么区别

在前端的时候,我们经常会轮询接口或定时去做一些事情,但是我们一般不使用 setInterval,因为浏览器中, setInterval 是用单独的线程实现的,当任务超市时,定时线程就会往 JS 线程追加一个回调任务。哪怕 JS 线程阻塞了,也不影响定时线程往 JS 线程里追加任务。如果 JS 线程在运行一段耗时的代码,定时线程就会往 JS 线程里追加很多回调任务,导致耗时代码执行完后,大量回调被执行,比如短期内大量的轮询接口请求,这并不是我们预期的效果。所以这种场景下一般使用 setTimeout 里调用 setTimeout 去模拟 setInterval。但在 Node.js 里就不会存在这个问题,首先 Node.js 定时器不是单独线程实现的,然后当 setInterval 的回调被执行时,才会开始开始下一轮的计时。下面是 Node.js 中的实现,我们可以看到执行回调前会重新获取当前时间为下一轮开始时间,然后重新插入数据结构中。

3 如何在 Node.js 里监听一个随机端口

在某些场景下,我们可能需要监听一个随机的端口,在 Node.js 里我们可以这样做

  1. const server  = net.createServer() 
  2. .listen(() => { 
  3.     console.log(server.address()); 
  4. }) 

但是这种方式存在一个问题是在 cluster 模块下无法正常工作,比如我们希望在每一个进程里监听不同的随机端口,那么在子进程里执行 listen 的时候,不管是使用 cluster 的哪种模式都会导致多个进程监听同一个端口,解决方案就是使用 exclusive 标记。

  1. const server  = net.createServer() 
  2. .listen({ port: 0, exclusive: true }, () => { 
  3.     console.log(server.address()); 
  4. }) 

 

exclusive 指示 Node.js 不共享监听端口,而是每次都监听一个新的端口,至于为啥要穿 port 等于 0,因为 Node.js 里的逻辑就是这样的。

 

责任编辑:武晓燕 来源: 编程杂技
相关推荐

2014-10-13 10:41:48

安防布线

2023-06-20 06:44:14

Node.jsCPU 负载

2020-11-05 09:27:48

JavaScript开发技术

2023-08-04 08:20:56

DockerfileDocker工具

2023-08-10 08:28:46

网络编程通信

2021-01-12 05:08:49

DHCP协议模型

2022-05-24 08:21:16

数据安全API

2022-03-31 18:59:43

数据库InnoDBMySQL

2022-10-18 07:33:57

Maven构建工具

2021-08-27 07:06:09

DubboDocker技术

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷开发模式

2023-08-14 08:38:26

反射reflect结构体

2023-09-29 08:58:38

2024-02-20 21:34:16

循环GolangGo

2022-01-17 06:59:40

Grep指令linux

2021-12-29 08:27:05

ByteBuffer磁盘服务器

2021-08-27 07:06:10

IOJava抽象

2021-07-28 07:53:20

Github ActiDotnet 应用

2022-03-08 17:52:58

TCP格式IP
点赞
收藏

51CTO技术栈公众号