【问题标题】:Promise inside loop in nodejs isn't working as expectednodejs中循环内的承诺没有按预期工作
【发布时间】:2015-07-23 12:04:51
【问题描述】:

我有一系列事件,对于每个值,可能/可能不会查询触发以获取数据。

var eventTypes = [["write","write","write","write"],["write","write","read","write"]];
_.each(eventTypes,function(obj){
        gettime(obj);
 });


gettime=function(events){
   var resultArray = [];
   _.each(events,function(event){
      if(event === "read"){
         resultArray.push(makesqlquery(event));
      }else{
         resultArray.push({"time":current_time})
      }
   });
   q.all(resultArray).then(function(finalResult){
        insertIntoPostgreSQL(finalResult);
   });
}

makesqlquery = function(event){
   var deferred = q.defer();
   sql.query("select time from events where eventtype ="+ event,
      function(result,error){
        if(error){
          deferred.reject(error);
        }else{
          deferred.resolve({time:result.time});
        }
    });
   return deferred.promise;
}

在上面的代码中,我可以将第一组数据(["write","write","write","write"]) 推送到postgresql 数据库中,但不能推送第二组数据(["write","write","re​​ad","write"]) .每当我在集合中得到read 事件时,我都会得到空对象。会有什么问题?对于上面的示例,我应该在 postgresql 中有 8 条记录,但我只看到第一个数组的四个数据。

更多信息: insertIntoPostgreSQL() 函数将获取对象列表并将每个对象插入数据库。此操作运行良好。

我尝试使用两个控制台 stmt 作为

console.log("sql result:"result);
deferred.resolve({time:result.time}); 

console.log("Before Insert:"JSON.stringigy(resultArray));
q.all(resultArray).then(function(finalResul‌​t){ 

我按以下顺序得到结果。

插入前:[{"source":{}},{"source":{}},{"source":{}},{"source":{}}]

插入前:[{}]

sql结果:{time:"2015-07-10 00:00:00"}

【问题讨论】:

  • 我可能遗漏了其他内容,但您确定 insertIntoPostgreSQL 函数在“finalResult”中有选择查询吗?这意味着承诺正在兑现。
  • function(finalResult){insertIntoPostgreSQL(finalResult);}); 回调甚至没有为read 事件执行。
  • 目前,您的代码所说的是,在 -all- 事件完成后(q.all),然后将触发匿名函数(finalResult)。这应该只发生一次。 finalResult 然后应该包含时间:来自您的选择回调的结果。
  • q.all() 返回的promise 可能走的是错误路径。尝试添加一个处理程序以使错误可观察,即.then(insertIntoPostgreSQL, errorHandler)
  • 我已经用更多信息更新了我的问题。 @Spork

标签: node.js promise


【解决方案1】:

正如在 cmets 中提到的 Roamer-1888,请务必为您的 Q.all 添加错误处理程序。您的承诺的基本结构似乎很好,错误在其他地方。

看起来您的sql.query 回调中的result 与您期望的不太一样,因为它被读取为undefined。由于那里出现错误,Q.all 没有得到解决,因此没有任何内容添加到您的数据库中。

【讨论】:

  • 我尝试使用两个控制台 stmt 作为 console.log("sql result:"result);deferred.resolve({time:result.time});console.log("Before insert:"JSON.stringigy(resultArray));q.all(resultArray).then(function(finalResult){ 我按以下顺序得到结果。 Before insert:[{"source":{}},{"source":{}},{"source":{}}] 在下一行 sql result:{time:"2015-07-10 00:00:00"}
  • 您可以尝试deferred.resolve({time:result || 0}); 看看是否将q.all(...) 发送到成功路径。如果是这样,您应该会看到一个0 出现在数据库中。真正的解决办法当然在其他地方,但至少这会让你对整个过程更有信心。
  • 或者deferred.resolve({time:result.time || 0});
猜你喜欢
  • 2018-09-19
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
相关资源
最近更新 更多