简体   繁体   English

如何使用async.parallel()使for循环工作

[英]how to make a for loop work with a async.parallel()

I am using Sails, Waterline and Async library 我正在使用Sails,Waterline和Async库

function Outerfunction(listOfProducts) {
  var salesOrderId = 1; //some id
  var prom = [];
  for (var i = 0; i < listOfProducts.length; i++) {
    var qty = listOfProducts[i].quantity;
    var prod = listOfProducts[i].productName;
    var update = function(qty, prod, SalesOrderId) {
      CardImages.update({
          where: {
            productName: prod,
            isSold: false,
            readyToSell: true
          }
        }, {
          order: SalesOrderId,
          isSold: true
        })
        .exec(function(err, updatedRecords) {
          if (err) return err;
          return updatedRecords;
        });
    }
    prom.push(update);
  }
  async.parallel(prom, function(err, result) {

    //this callback never gets called
    console.log("database calls done");
  });
}

I am trying to update database with a for loop, this code works fine and updates the database but but my callback with async.parallel won't get called when all the records are updated. 我试图用for循环更新数据库,这段代码工作正常并更新数据库,但是当所有记录都更新时,我的回调与async.parallel不会被调用。

The function you are looking for is async.map , which will apply an asynchronous function to each element in an array, and call back with an array of results. 您正在寻找的函数是async.map ,它将异步函数应用于数组中的每个元素,并使用一组结果回调。 I can't test this, but something like this should work: 我无法测试这个,但这样的事情应该有效:

function OuterFunction(listOfProducts) {
  var salesOrderId = 1;  // some id

  async.map(listOfProducts, function (product, done) {
    // for each product, update its DB entry
    CardImages.update({
      productName: product.productName,
      isSold: false,
      readyToSell: true
    }, {
      order: salesOrderId,
      isSold: true
    }).exec(done);  // indicate that async work is done
  }, function (err, result) {
    // all finished
    console.log('database calls done');
  });
}

Note that this solution does not use Promises at all . 请注意,此解决方案根本不使用Promise This is simply callback-based asynchronous work. 这只是基于回调的异步工作。


I have not worked with Waterline, but based on what I quickly found in the (rather bad) documentation, this is also a possible solution: 我没有使用过Waterline,但根据我在(相当糟糕的)文档中快速找到的内容,这也是一个可能的解决方案:

function OuterFunction(listOfProducts) {
  var salesOrderId = 1;  // some id
  // extract product names
  var productNames = listOfProducts.map(function (product) {
    return product.productName;
  });

  // update in bulk
  CardImages.update({
    productName: productNames,
    isSold: false,
    readyToSell: true
  }, {
    order: salesOrderId,
    isSold: true
  }).exec(function (err, results) {
    // all finished
    console.log('database calls done');
  });
}

Translated to SQL, the first solution would emit (roughly) 转换为SQL,第一个解决方案会发出(大致)

UPDATE table SET isSold = TRUE, readyToSell = FALSE
WHERE productName = 'product 1' AND isSold = FALSE AND readyToSell = TRUE;

UPDATE table SET isSold = TRUE, readyToSell = FALSE
WHERE productName = 'product 2' AND isSold = FALSE AND readyToSell = TRUE;

UPDATE table SET isSold = TRUE, readyToSell = FALSE
WHERE productName = 'product 3' AND isSold = FALSE AND readyToSell = TRUE;

...

and the second would emit the more efficient 而第二个会发出更高效的

UPDATE table SET isSold = TRUE, readyToSell = FALSE
WHERE productName IN ('product 1', 'product 2', 'product 3', ...)
  AND isSold = FALSE AND readyToSell = TRUE;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM