Javascript Node.js:http.request()在setImmediate()之后触发

Javascript Node.js:http.request()在setImmediate()之后触发,javascript,node.js,event-loop,setimmediate,Javascript,Node.js,Event Loop,Setimmediate,我在Node中是新手,因此我不清楚以下代码行为: function step(iteration) { if (iteration === 10) return; process.nextTick(() => { step(iteration + 1); // Recursive call from nextTick handler. console.log(`nextTick iteration: ${iteration}`); }); htt

我在Node中是新手,因此我不清楚以下代码行为:

function step(iteration) {
  if (iteration === 10) return;

  process.nextTick(() => {
    step(iteration + 1); // Recursive call from nextTick handler.
    console.log(`nextTick iteration: ${iteration}`);    
  });

  http.request({hostname: '127.0.0.1', port: 5000}, (response) => {
    console.log("here !");
  }).end();

  setImmediate(() => {
    console.log(`setImmediate iteration: ${iteration}`);    
  });
}
step(0);
输出:

nextTick iteration: 0
...
nextTick iteration: 9
setImmediate iteration: 0
...
setImmediate iteration: 9
here !
here !
here !
here !
here !
here !
here !
here !
here !
here !
问题是:

1) 为什么
http.request()
回调在
setImmediate()之后触发?我不明白,为什么通常调用
setImmediate()
:它的回调是在循环期间注册的。但正如文档所述,
setImmediate()
是一个检查阶段,应该在轮询一次之后在事件循环中进行处理。如果我理解正确的话,
http.request()
之后的
nextTick()
应该是轮询阶段

2) 但是,如果在轮询中未处理http.request()
,它将在哪个阶段发生?特别是考虑到它在
setImmediate()
之后工作


我的Node.js版本是6.11.2。提前感谢您的解释。

要回答您的问题:

  • http.request()
    setImmediate()之前调用。但是,
    http.request
    是异步的。在您的情况下,只有在请求解析之后才会运行回调。这意味着,尽管先调用回调函数,但回调函数不会记录任何内容,直到稍后的某个时间点,并且该时间点是在
    setImmediate()
    解析之后
  • 即使
    setImmediate
    将其回调按其排队顺序排队执行,它们仍然能够在请求返回之前解析
  • 为了处理您的步骤,请考虑将<代码> NEXTICK/<代码>的内容移动到请求的回调中:

    function step(iteration) {
      if (iteration === 10) return;
    
      http.request({hostname: '127.0.0.1', port: 8000}, (response) => {
        console.log("here !");
    
        step(iteration + 1); // Recursive call from nextTick handler.
    
        console.log(`nextTick iteration: ${iteration}`);    
      }).end();
    
      setImmediate(() => {
        console.log(`setImmediate iteration: ${iteration}`);    
      });
    }
    step(0);
    

    在该代码段中,我删除了
    nextTick
    ,不过如果需要,您可以安全地将其添加到回调中。

    它稍后会记录它,因为它正在等待响应。虽然先调用
    http.request()
    ,回调直到稍后的时间点才记录任何内容,而该时间点在
    setImmediate()之后
    已解决。-请给我一个关于文档的链接,好吗?因为我已经读过:如果轮询队列(我假设,
    http.request()
    在该队列中)不是空的,那么事件循环将遍历同步执行它们的回调队列。。。如果setImmediate()已计划脚本,则事件循环将结束轮询阶段,并继续到检查阶段以执行这些计划脚本。因此,我建议提前触发请求回调,即
    setImmediate
    的回调。您链接到的文档是正确的,但它不适用于传递到
    .request()
    的回调。在下,它指出:“可选回调参数将作为‘响应’事件的一次性侦听器添加。”即使通过立即执行
    .request()
    ,也会异步接收响应。如果您监听
    请求上的立即回调,如
    request.on('socket',…)
    ,它看起来是同步的,并且在
    setImmediate
    之前记录,则可以看到这一点。