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

时间:2017-08-24 22:17:54

标签: 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}`);    
  });

  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() check 阶段,应在 poll 之后的事件循环中处理。如果我理解正确,http.request()之后的nextTick()应该是民意调查阶段;

2)但是如果 poll 中没有处理http.request(),它会在什么阶段发生?特别是考虑到它在setImmediate()之后起作用。

我的Node.js版本是6.11.2。在此先感谢您的解释。

1 个答案:

答案 0 :(得分:-1)

回答你的问题:

    http.request()之前
  1. setImmediate() 调用。但是,http.request是异步的。在您的情况下,直到请求结算后才会运行回调。这意味着虽然它首先被调用,但回调不会记录任何内容,直到稍后的时间点 - 并且该点在setImmediate()已解决之后。
  2. 即使setImmediate按照排队顺序对其回调进行排队,但在请求返回之前,它们仍然可以解析。
  3. 为了按顺序处理您的步骤,请考虑将nextTick的内容移至请求的回调中:

    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,但如果需要,您可以安全地将其添加到回调中。