node.js和setTimeout以及setInterval - 理解事件循环

时间:2013-06-14 06:20:36

标签: javascript node.js asynchronous settimeout event-loop

我编写了下面的程序,努力理解事件循环和setTimeout和setInterval等函数。

该计划的输出与我的预期不同:

  

输出结果为:

In F
In L
Padalia
outside all
callback1
callback2
From Interval:0
From Interval:1
From Interval:2
From Interval:3
  

问题:

  1. 为什么“oustside all”不是先执行?
  2. 为什么间隔总是最后执行?
  3. 有人可以向我解释整个程序的执行情况。
  4. 在退出程序之前等待一段时间,为什么?
  5.   

    方案:

    var Fname = undefined;
    var Lname = undefined;
    var count = 0;
    
    function F(callback){
      console.log("In F");
      Fname = "Rushabh";
      if(Fname != undefined && Lname != undefined) { 
        console.log(Fname);
        }      
      process.nextTick(function() { 
        callback();
      });
    //callback();
    }
    
    function L(callback){
      console.log("In L");
      Lname = "Padalia";
      if(Fname != undefined && Lname != undefined) { 
        console.log(Lname);
      } 
      process.nextTick(function() {callback();});
    //callback();
    } 
    
    function compute(){
    
      Id = setInterval(function() {
        console.log("From Interval:" + count); count++;
        if(count > 3){
          clearInterval(Id);
        }
      }, 100)
    
     setTimeout(F(function(){
      console.log("callback1");
     }),5000);
    
     setTimeout(L(function(){
      console.log("callback2");
     }) , 5000);
    
     console.log("Outside all");
    }
    
    compute();
    

2 个答案:

答案 0 :(得分:5)

您在设置FL超时的代码中存在错误。您的代码等同于:

/* ... */

F(function(){
  console.log("callback1");
});
setTimeout(undefined ,5000);

L(function(){
  console.log("callback2");
});
setTimeout(undefined, 5000);

/* ... */

现在应该清楚为什么你的程序不像你期望的那样:

  1. 首先执行“所有外部”,因为您之前正在调用FL
  2. 由于同样的原因,最后执行间隔。
  3. 对于您使用undefined回调设置的两次超时,程序会等待5秒钟。
  4. 如何修复代码的最简单方法是为setTimeout调用添加匿名回调函数:

     setTimeout(function() { F(function(){
      console.log("callback1");
     })},5000);
    
     setTimeout(function() { L(function(){
      console.log("callback2");
     })} , 5000);
    

    或者,您可以使用bind来固定FL个参数(bind的第一个参数是this的值):

    setTimeout(F.bind(null, (function(){
     console.log("callback1");
    })),5000);
    
    setTimeout(L.bind(null, (function(){
     console.log("callback2");
    })) , 5000);
    

答案 1 :(得分:0)

您还可以按如下方式更改setTimeout,

...
 setTimeout(F,5000,function(){
  console.log("callback1");
 });

 setTimeout(L,5000,function(){
  console.log("callback2");
 });
...

由于setTimeout函数不会将参数直接带到您的函数,您需要在后续参数中发送它们。

setTimeout(function,milliseconds,param1,param2,...)