本文转载自微信公众号《编程杂技》,作者theanarkh。转载本文请联系编程杂技公众号。一问一答,就是以问答的形式,谈谈Node.js的知识点。1SetTimeout和setImmediatesetTimeout(()=>{},0)和setImmediate,先执行谁?这是Node.js中经常提到的一个问题。其实这两者没有任何关系。setImmediate是Node.js检查阶段的任务,setTimeout是定时器阶段的任务。在Node.js事件循环中,定时器阶段在检查阶段执行。貌似setTimeout的回调必须在setImmediate的回调之前执行,但是Node.js的实现规定了setTimeout的超时时间最小为1,这就导致了事件循环开始的时候,定时器可能或者可能不会过期,所以不确定谁先执行。下面是示例代码。setTimeout(()=>{console.log('setTimeout')},0);setImmediate(()=>{console.log('setImmediate')});2浏览器和Node的setInterval有什么区别。js在前端,我们经常轮询接口或者定时做一些事情,但是我们一般不会使用setInterval,因为在浏览器中,setInterval是用一个单独的线程来实现的。当任务被取代时,定时线程会去JS线程追加一个回调任务。即使JS线程被阻塞,也不会影响定时线程向JS线程添加任务。如果JS线程正在运行一段耗时代码,定时线程会给JS线程添加很多回调任务,导致执行完耗时代码后会执行大量的回调,比如大量的回调在短时间内轮询接口请求。我们预期的效果。所以在这种场景下,在setTimeout中调用setTimeout来模拟setInterval。但是在Node.js中不存在这个问题。首先,Node.js计时器不是由单独的线程实现的。然后,当setInterval的回调执行时,就会开始下一轮计时。以下是Node.js中的实现。我们可以看到,在执行回调之前,会获取当前时间作为下一轮的开始时间,然后重新插入到数据结构中。3如何在Node.js中监听一个随机端口在某些场景下,我们可能需要监听一个随机端口,在Node.js中我们可以这样做constserver=net.createServer().listen(()=>{console.log(server.address());})但是这个方法有个问题,在cluster模块下无法正常工作。比如我们想在每个进程中监听不同的随机端口,那么在子进程中执行listen使用集群时,无论使用哪种集群模式,多个进程都会监听同一个端口。解决方案是使用独占标志。constserver=net.createServer().listen({port:0,exclusive:true},()=>{console.log(server.address());})exclusive指示Node.js不要共享监听端口,但它每次都会监听一个新端口。至于为什么端口等于0,因为Node.js中的逻辑是这样的。
