Javascript nodejs等待循环中的所有MongoDB调用完成
我正在逐行读取CSV文件中的数据流,并在每一行上调用findOne MongoDB调用,如何等到每一行的所有mongo调用完成后再运行下一个函数 我见过承诺能做到吗?但我发现承诺极难理解。我发现的例子中似乎没有一个能涵盖我想要表达的内容/Javascript nodejs等待循环中的所有MongoDB调用完成,javascript,node.js,mongodb,asynchronous,promise,Javascript,Node.js,Mongodb,Asynchronous,Promise,我正在逐行读取CSV文件中的数据流,并在每一行上调用findOne MongoDB调用,如何等到每一行的所有mongo调用完成后再运行下一个函数 我见过承诺能做到吗?但我发现承诺极难理解。我发现的例子中似乎没有一个能涵盖我想要表达的内容/ var validProducts = []; fs.createReadStream(req.file.path) .pipe(csvStream) .on('error', function (err) { console.error(e
var validProducts = [];
fs.createReadStream(req.file.path)
.pipe(csvStream)
.on('error', function (err) {
console.error(err);
})
// loop through all rows
.on('data', function (data) {
if (data.size === 'a3') {
ProductModel.findOne({ sku: data.sku }, function (err, product) {
if (product !== null) {
product.size = data.size;
product.save();
validProducts.push(product);
}
});
}
});
// on finish make call to other function
socket.emit({ 'status': 'complete' });
otherFunction(validProducts);
on('finish')
或on('end')
将仅在数据流的末尾调用,而不是在Monogo调用之后
如果我能使用承诺,有人能解释一下如何使用吗/
您可以使用允许您做出承诺的API。有一个有趣的函数,允许您等待一系列承诺得到解决。下面是一个如何使用Q解决问题的示例。all
:
var validProducts = [];
var promises = [];
function handleData(data) {
if (data.size === 'a3') {
var deferred = Q.defer();
ProductModel.findOne({ sku: data.sku }, function (err, product) {
if (err) {
deferred.reject(new Error(err));
}
if (product) {
product.size = data.size;
product.save();
deferred.resolve(product);
validProducts.push(product);
}
});
promises.push(deferred.promise);
}
}
function handleEnd() {
Q.all(promises).done(function (values) {
socket.emit({ 'status': 'complete' });
otherFunction(validProducts);
});
}
fs.createReadStream(req.file.path)
.on('data', handleData)
.on('end', handleEnd);
这不是使函数同步,而不是异步吗?关闭。但是
.resume()
和.push()
需要在.save()
的回调内部进行。也不确定这个是否公开,所以您可能需要首先从外部获取流。它是数据库的I/O函数。节点中几乎所有的I/O都是异步的,或者应该是异步的。实际上,我想我不知道问题是什么:D-我想,每一行
都是由on('data'
函数处理的。I/O是异步的,但是如果流暂停到前一行完成,那么一次只会发生一个mongo调用,这使得它是同步的(技术上),同时也(技术上)回答我的问题..ish.:P我自己就很接近这个问题,。但是没有正确设置延迟的内容。这不会等到每行的所有mongo调用都完成,然后再运行下一个函数也许我的逻辑有缺陷?如果我错了,请纠正我,但是当没有更多数据可从文件读取时,我们正在等待所有的数据承诺将在执行指定函数之前解析。如果我的想法正确,则流将在向promises
数组添加任何内容之前end
。因此Q.all(承诺)
将立即执行。:/事实上最初有一个输入错误!我编辑了它,我认为它会被忽略。这是一种乐趣;)
var validProducts = [];
var promises = [];
function handleData(data) {
if (data.size === 'a3') {
var deferred = Q.defer();
ProductModel.findOne({ sku: data.sku }, function (err, product) {
if (err) {
deferred.reject(new Error(err));
}
if (product) {
product.size = data.size;
product.save();
deferred.resolve(product);
validProducts.push(product);
}
});
promises.push(deferred.promise);
}
}
function handleEnd() {
Q.all(promises).done(function (values) {
socket.emit({ 'status': 'complete' });
otherFunction(validProducts);
});
}
fs.createReadStream(req.file.path)
.on('data', handleData)
.on('end', handleEnd);