Javascript nodejs等待循环中的所有MongoDB调用完成

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

我正在逐行读取CSV文件中的数据流,并在每一行上调用findOne MongoDB调用,如何等到每一行的所有mongo调用完成后再运行下一个函数

我见过承诺能做到吗?但我发现承诺极难理解。我发现的例子中似乎没有一个能涵盖我想要表达的内容/

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);