了解回调

Understanding Call backs

我创建了一个小脚本来更好地理解回调。

从下面的脚本中,我预期的行为是:"http.get runs and takes on average 200 ms. The for loop "i" 增量平均需要 2500 毫秒。在 200 毫秒时,进程应该退出并且脚本应该停止工作。为什么会这样打印所有 i?如果我能更好地理解这一点,我想我就理解回调了。

var http = require("http");
var starttime = new Date();

//Function with Callback
for (var j =0; j<10; j++){
    http.get({host : 'nba.com'}, function(res){
        console.log("Time Taken = ", new Date() - starttime, 'ms');

        process.exit();
    }).on('error', function(er){
        console.log('Got Error :', er.message);
    })
}

//Loop that exceeds callback trigger time
for(var i=1; i<10000; i++){
    console.log(i);
}

console.log("Time Taken = ", new Date() - starttime, 'ms');
node.js 中的

Javascript 是单线程的,I/O 是使用事件队列的事件驱动。因此,表示 http 请求完成的异步回调不能 运行,直到 Javascript 的原始线程完成并且 returns 控制权回到系统,然后它可以从中提取下一个事件为完成 http 请求提供服务的事件队列。

因此,您的 for 循环将 运行 在处理任何 HTTP 响应之前完成。

这是分步过程:

  1. 您的第一个 for 循环 运行 并发送 10 个 http 请求。
  2. 这些 http 请求 运行 在后台使用异步网络。当其中一个完成并有响应时,http 模块会将一个事件放入 Javascript 事件队列中,JS 解释器的工作是在完成其他活动时从事件队列中拉出该事件.
  3. 你的第二个 for 循环 运行s 完成,所有 i 值都输出到控制台。
  4. 您的脚本完成。
  5. 然后 JS 解释器检查事件队列以查看是否有任何未决事件。在这种情况下,会有一些http响应事件。 JS 解释器从事件队列中提取最旧的事件并调用与之关联的回调。
  6. 当该回调完成时,下一个事件将从事件队列中拉出并继续该过程,直到事件队列为空。
  7. 如果您的任何回调调用 process.exit(),那么这会使剩余的回调短路并立即退出进程。

虽然这个其他答案是为浏览器编写的,但事件驱动的单线程概念与 node.js 中的相同,所以这个其他答案可能会为您解释更多内容:How does JavaScript handle AJAX responses in the background?