node.js async.eachSeries 过早调用最终回调
Posted
技术标签:
【中文标题】node.js async.eachSeries 过早调用最终回调【英文标题】:node.js async.eachSeries calling final callback too early 【发布时间】: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') 显示之后。我需要的是一种在我的数组中的所有项目都已处理完之后显示“全部完成”的方法
【参考方案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();解决方案并停止流,直到异步响应到来。可能有点难看,但它对我有用。非常感谢您的意见!以上是关于node.js async.eachSeries 过早调用最终回调的主要内容,如果未能解决你的问题,请参考以下文章
node.js async.eachSeries 过早调用最终回调