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

Nic*_*iwi 5 javascript asynchronous mongodb node.js promise

我正在逐行读取CSV文件中的数据流,并在每一行上调用findOne MongoDB调用,在运行下一个函数之前,我怎么能等到每行的所有mongo调用完成?

我见过Promises可以做到吗?但我觉得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);
Run Code Online (Sandbox Code Playgroud)

on('finish')或者on('end')只会在数据流结束时调用,而不是在Monogo调用之后调用.

如果我可以使用承诺,有人可以解释一下吗?

Phi*_*bby 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);
Run Code Online (Sandbox Code Playgroud)