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

Node.js: http.request() triggers after 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 之后在事件循环中处理。如果我没理解错的话,nextTick()之后的http.request()应该是poll阶段;

2) 但如果 http.request() 没有在 poll 中处理,它发生在哪个阶段?特别是考虑到它在 setImmediate().

之后起作用

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

回答您的问题:

  1. http.request() setImmediate() 之前调用。但是,http.request 是异步的。在您的情况下,回调不是 运行 直到请求解决之后。这意味着虽然它首先被调用,但回调不会记录任何内容,直到稍后的某个时间点——那个时间点是在 setImmediate() 已经解决之后。
  2. 即使 setImmediate 按照排队的顺序将其回调排队执行,它们仍然能够在请求 returns.
  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,但如果需要,您可以安全地将其添加到回调中。