【问题标题】:node js :-null value error in for loop节点js:-for循环中的空值错误
【发布时间】:2015-07-02 06:02:13
【问题描述】:

嗨,我是 nodejs 的新手,我正在尝试实施一个项目,在该项目中,我们必须在事件管理站点中......我们正在为特定用户的页面添加事件。

现在的问题是我被困在这一点上:-

   exports.getDashBoard=function(req,res){
    var eventList=[];
       for(var i=0;i<req.user.invites.length;i++)
       {
                   Event.find({_id:req.user.invites[i]},function(err,events){
                   if(err)
                   {
                   console.log(err);  
                   }
                   else
                   {
                    eventList.push(events[0]);
                    console.log(eventList);
                    // shows value inside the array as wanted
                   }
                 });
       }
    console.log(eventList);
                // shows null value why? the variable is in the scope as its declaration 

   res.render('dashboard');
   };

说明: 我创建了一个函数,每次调用该函数时,我都会在其中声明和初始化变量 eventList。我在一个内部函数中使用了这个变量 eventList 来更新它的值并连接到以前的值。console.log 显示 eventList 正在根据需要更新。但是当我尝试在内部函数之外使用这个变量时是 doenst工作,我得到一个初始化的空数组变量的范围是本地的,在主函数中并且在内部函数内部可见但是当我在内部函数之后使用它时,即在for循环之外,数组显示空值 怎么办?

下图:- 我创建了一个函数,每次调用该函数时,我都会在其中声明和初始化变量 eventList。我在一个内部函数中使用了这个变量 eventList 来更新它的值并连接到 previoys 值。console.log 显示 eventList 正在根据需要更新。但是当我尝试在内部函数之外使用这个变量时是 doenst工作,我得到一个初始化的空数组变量的范围是局部的,在主函数中并且在内部函数中可见但是当我在内部函数之后使用它时消失了

怎么办?

【问题讨论】:

    标签: javascript arrays json node.js callback


    【解决方案1】:

    您在eventList 实际填充之前打印它。您正在将项目附加到 eventList 内的 Event.find 回调中,当您执行外部 console.log(eventList); 时可能尚未执行。

    编辑:
    要在调用所有回调后打印集合,如果您在最后一次迭代中,您可以检查回调,如果是,则打印 eventList

    if(i===(req.user.invites.length-1)){
        console.log(eventList);
    }
    

    您可以/应该考虑更详细的内容,如 async.js 或一些承诺库(如 Q)。 使用 async.js,您的代码将类似于(未经测试):

    async.eachSeries(req.user.invites, function (invite, callback) {
      Event.find({_id:invite}, function(err,events){
        if(err) {
          console.log(err);
          throw err;   
        } else {
          eventList.push(events[0]);
          console.log(eventList);
        }
      }
    }, function (err) { // called once all iteration callbacks have returned (or an error was thrown)
      if (err) { throw err; }
      console.log(eventList); // Final version of eventList
    });
    

    【讨论】:

    • 。我明白了,但我想显示所有事件,并且在回调完全执行后才有可能。我不知道该怎么做。你能帮我吗
    • @PrathameshP 我编辑了我的答案以提供更多细节
    【解决方案2】:

    在循环结束之前调用 Console.log。

    您可以在内部函数中检查最后一个循环并在为 true 时调用:

    if(err)
    {
    
        console.log(err);  
    }
    else
    {
    
        eventList.push(events[0]);
        console.log(eventList);
        // shows value inside the array as wanted
    
    // Check if its the last loop, if so, print eventList
    if(i==(req.user.invites.length-1)){
    
        console.log(eventList);
    }
    

    }

    【讨论】:

      【解决方案3】:

      为什么显示空值?该变量在其声明的范围内

      for(var i=0;i<req.user.invites.length;i++)
             {
         // time taking task. probably db call.         
      }
      console.log(eventList); 
      

      这是因为js是异步的。

      在你的 for 循环中它们存在一个耗时的任务,因此一旦 for 循环迭代结束,js 指针将移动到下一行(console.log)。注意:只有迭代结束,但任务仍在进行中,稍后这些任务完成时会调用它们的回调。

      模拟:

      function(){
          for(var i =0;i<5;i++){
              setTimeout(function(){
                  console.log('time taking task is over now.');
              }, 100);
          }
          console.log('I am after for loop');
      }
      

      在这里,输出将如下所示:

      I am after for loop
      time taking task is over now.
      time taking task is over now.
      time taking task is over now.
      time taking task is over now.
      time taking task is over now.
      

      简而言之,您需要通过确定哪些任务是耗时的任务以及哪些任务依赖于它们来管理您的工作流程。将所有这些依赖的任务放在任务的回调中(这种方法虽然解决了问题,但随着需求的扩展,这会产生Callback hell/pyramid of doom的新问题。请参阅promises了解即将到来的回调地狱)。

      此外,您还可以使用async 等工作流管理库,它将为您管理工作流。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-27
        • 1970-01-01
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多