的Node.js:()setImmediate后http.request()触发
我在节点是新的,所以下面的代码的行为是不明确的对我说:的Node.js:()setImmediate后http.request()触发
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);
OUTPUT:
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
将它的回调按其排队顺序排队执行,但它们仍然能够在请求返回前解析。
为了处理为了你的脚步,考虑移动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
,虽然你如果需要可以安全地将其添加到回调中。
_尽管先调用'http.request()',回调不记录任何内容,直到稍后的时间点 - 并且该点位于' setImmediate()'已经解决了._ - 你能给出一个关于文档的链接吗? –
因为我读过[反面](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#poll):_如果轮询queue_(我认为,http。 request()'在该队列中)_is不为空,则事件循环将遍历其同步执行它的回调队列。如果脚本已由setImmediate()调度,则事件循环将结束轮询阶段并继续执行这些预定脚本的检查阶段。因此,我建议早期触发请求的回调,即setImmediate是一个。 –
您链接到的文档是正确的,但它不适用于传递给'.request()'的回调。在https://nodejs.org/api/http.html#http_http_request_options_callback下,它注意到:“可选的回调参数将作为'响应'事件的一次性侦听器添加。” 即使通过'。request()'正在被立即执行,响应被异步接收。你可以看到这个,如果你听到'request'的即时回调,比如'request.on('socket',...)',它似乎是同步的,并且记录在'setImmediate'之前。 – Hans
它稍后记录它,因为它正在等待*响应* – 2017-08-24 22:31:51