【问题标题】:node.js async.eachSeries calling final callback too earlynode.js async.eachSeries 过早调用最终回调
【发布时间】:2014-03-10 19:58:17
【问题描述】:

这就是我想要的:我有一个名为 results 的大数组。我想将该数组中的每个项目放入我的迭代函数中并将其保存到我的 mongoDB 中(我在这里也省略了一些不重要的步骤)。在将这些项目中的每一项都保存到数据库(或拒绝)之后,我希望 console.log 显示“全部完成”。不幸的是,在调用系列后几乎立即显示所有完成,而其他一切仍在处理中。我该怎么做?

我将猫鼬与一个名为“light”的模型一起使用,为了便于阅读,我省略了代码中的所有错误消息。我对 eachSeries 部分使用节点异步

var async = require('async');    
var results = [very big array]
var iteration = function(row,callbackDone) {
  light.find({data: row.data}, function (err,entry) {
    if(entry.length) {
      callbackDone();
      return console.log(entry + ' already exists');
    }
    var newEntry = new light(row);
    newEntry.save(function (err,doc) {
      console.log(entry + ' saved');
      callbackDone();
    });
  });
};

async.eachSeries(results,iteration, function (err) {
  console.log('All done');
});

【问题讨论】:

  • 尝试添加一些错误记录器 (if (err) console.log(err);)。
  • 为了便于阅读,我删除了错误记录器。对不起,如果我不清楚。该数组很容易有 100 多个条目,猫鼬操作完美无缺,但所有保存都发生在 console.log('all done') 显示之后。我需要的是一种在我的数组中的所有项目都已处理完之后显示“全部完成”的方法

标签: javascript node.js mongodb asynchronous


【解决方案1】:

(答案,不是评论,因为文字太长了……)

我也在使用异步,你的问题让我很困惑。我尝试了下面的代码,结果更进一步。它对我来说很好。 (异步 0.2.9)。甚至将我的超时延迟更改为 0。

唯一看起来奇怪的是回调后的if(entry.length) 块打印控制台信息。如果您收到很多“已经存在”的消息,我可能会看到它们稍后会出现 - 但这听起来不像您所描述的那样。

var async = require('async');  
var console = require('console');
var results = [ ];
results.push( {id:1,data:'a'} );
results.push( {id:2,data:'b'} );
results.push( {id:3,data:'c'} );
results.push( {id:4,data:'d'} );

function doFind( obj, callback ) {
  setTimeout( function() {
    console.log( "finding id=" + obj.data.id );
    obj.data.length = obj.data.id % 2;
    callback( null, obj.data );
  }, 500 );
}

function light( obj ) {
  this.id = obj.id;
  this.data = obj.data;
  this.save = function( callback ) {
    setTimeout( function() {
      console.log( "saving id=" + obj.id );
      callback( null, this );
    }, 500 );
  };
}

var iteration = function(row,callbackDone) {
  doFind({data: row}, function (err,entry) {
    if(entry.length) {
      callbackDone(); 
      return console.log( 'id=' + entry.id + ' already exists');
    }
    var newEntry = new light(row);
    newEntry.save(function (err,doc) {
      console.log( 'id=' + entry.id + ' saved');
      callbackDone();
    });
  });
};

async.eachSeries(results, iteration, function (err) {
  console.log('All done');
});

结果

finding id=1
id=1 already exists
finding id=2
saving id=2
id=2 saved
finding id=3
id=3 already exists
finding id=4
saving id=4
id=4 saved
All done

【讨论】:

  • 您的示例也非常适合我,但由于某种原因我无法解决自己的问题。我切换到 var stream = light.find({}).stream();解决方案并停止流,直到异步响应到来。可能有点难看,但它对我有用。非常感谢您的意见!
猜你喜欢
  • 2016-04-14
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 2016-06-22
  • 2011-03-22
  • 2012-10-31
相关资源
最近更新 更多