在async.auto上迭代?

时间:2014-06-28 07:01:04

标签: node.js sails.js waterline async.js

以下是我的sailsJS代码段。这段代码对我有用。

afterCreate: function( value, callback ) {
    var getStock = function( cb ) {
      PurchaseInvoiceDetail
        .find({ product: value.product.id })
        .then(function( detail ) {
          cb(null, SharedInvoiceService.sumNumberArray(_.pluck(detail, 'quantity')));
        });
    };

    var updateStock = ['getStock', function( results, cb ) {
      Product.findOne(value.product.id).then(function( product ) {
        product.stock = results.getStock;
        product.save(cb);
      });
    }];

    async.auto({
      getStock: getStock,
      updateStock: updateStock
    }, function( results ) {
      console.log(results);
      callback();
    });
});

然后,我尝试将代码包装成像这样进行迭代

afterCreate: function( value, callback ) {
    _.each(value.details, function(valueDetail) {
        // wrapped
        var getStock = function( cb ) {
          PurchaseInvoiceDetail
            .find({ product: valueDetail.product.id })
            .then(function( detail ) {
              cb(null, SharedInvoiceService.sumNumberArray(_.pluck(detail, 'quantity')));
            });
        };

        var updateStock = ['getStock', function( results, cb ) {
          Product.findOne(valueDetail.product.id).then(function( product ) {
            product.stock = results.getStock;
            product.save(cb);
          });
        }];

        async.auto({
          getStock: getStock,
          updateStock: updateStock
        }, function( results ) {
          console.log(results);
          callback();
        });
        // end-of-wrapped
    });

});

它不像我预期的那样工作。那么,如何在async.auto上操作每个?

更新

斯科特格雷斯的答案更有意义,我尝试过,但我遇到了新问题,因为有时value.details没有价值。我修改了我的代码。

beforeCreate: function( value, callback ) {
  if (value.details) { // make sure value.details is defined
    console.log('called');
    async.each(value.details, function(valueDetail, eachCallback) {
      // wrapped
      var getStock = function( cb ) {
        PurchaseInvoiceDetail
          .find({ product: valueDetail.product.id })
          .then(function( detail ) {
            cb(null, SharedInvoiceService.sumNumberArray(_.pluck(detail, 'quantity')));
          });
      };

      var updateStock = ['getStock', function( results, cb ) {
        Product.findOne(valueDetail.product.id).then(function( product ) {
          product.stock = results.getStock;
          product.save(cb);
        });
      }];

      async.auto({
        getStock: getStock,
        updateStock: updateStock
      }, function( results ) {
        console.log(results);
        eachCallback();
      });
      // end-of-wrapped
    }, callback);
  } else {
    console.log('skipped');
    callback();
  }

},

现在,当我创建新数据时,我在控制台收到此错误。

called

C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sails\node_modules\wa
terline\lib\waterline\model\lib\defaultMethods\save.js:179
      cb(null, data);
      ^
TypeError: object is not a function
    at C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sails\node_mod
ules\waterline\lib\waterline\model\lib\defaultMethods\save.js:179:7
    at bound (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\lodash\
dist\lodash.js:957:21)
    at applyInOriginalCtx (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_mo
dules\sails\node_modules\waterline\lib\waterline\utils\normalize.js:409:80)
    at wrappedCallback (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modul
es\sails\node_modules\waterline\lib\waterline\utils\normalize.js:308:18)
    at _normalizeCallback.callback.success (C:\Users\Ryan\Dropbox\Projects\ShopA
ppBackend\node_modules\sails\node_modules\waterline\node_modules\node-switchback
\lib\normalize.js:33:26)
    at _switch (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sails
\node_modules\waterline\node_modules\node-switchback\lib\factory.js:35:28)
    at returnResults (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules
\sails\node_modules\waterline\lib\waterline\query\finders\basic.js:166:9)
    at C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sails\node_mod
ules\waterline\lib\waterline\query\finders\basic.js:136:9
    at integrate (C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sai
ls\node_modules\waterline\lib\waterline\query\integrator\index.js:217:10)
    at C:\Users\Ryan\Dropbox\Projects\ShopAppBackend\node_modules\sails\node_mod
ules\waterline\lib\waterline\query\finders\basic.js:87:7

2 个答案:

答案 0 :(得分:0)

您遇到的问题是由于async.auto调用在_.each内的第一次完整迭代中触发了afterCreate callback()。

有许多潜在的解决方案,但无论您使用何种解决方案,都需要每次迭代的内部包装。然后采用一些方法来收集每个迭代并激活afterCreate的回调()一次。

答案 1 :(得分:0)

你使用async.auto得到了正确的想法,但你通过选择同步_.each方法将其包起来放弃了它;你需要async.each代替:

afterCreate: function( value, callback ) {
    async.each(value.details, function(valueDetail, each_cb) {
        // wrapped
        var getStock = function( cb ) {
          PurchaseInvoiceDetail
            .find({ product: valueDetail.product.id })
            .then(function( detail ) {
              cb(null, SharedInvoiceService.sumNumberArray(_.pluck(detail, 'quantity')));
            });
        };

        var updateStock = ['getStock', function( cb, results ) {
          Product.findOne(valueDetail.product.id).then(function( product ) {
            product.stock = results.getStock;
            product.save(cb);
          });
        }];

        async.auto({
          getStock: getStock,
          updateStock: updateStock
        }, function( err, results ) {
          console.log(results);
          each_cb();
        });
        // end-of-wrapped
  }, 
  // Third argument to async.each is callback for when loop is finished
  callback);

}