我正逐行从CSV文件中读取数据流,并在每一行上调用findOne MongoDB调用,在运行下一个函数之前,我怎么能等到每行的所有mongo调用都完成? / p>
我见过Promise可以做到吗?但我觉得Promises极难理解。我发现的所有例子都没有涵盖我正在尝试的内容。 :/
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调用之后调用。
如果我可以使用承诺,有人可以解释一下吗?
答案 0 :(得分:4)
你可以使用Q 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);
答案 1 :(得分:3)