2014-06-28 50 views
0

以下是我的sailsJS代碼片段。這段代碼對我有用。async.auto上的迭代?

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進行操作?

UPDATE

斯科特·格雷斯的回答更有道理,我已經盡力了,但我得到了新的問題,因爲有時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 

回答

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

} 
+0

啊哈,謝謝你的回答。這對我來說更有意義。順便說一句,我修改我的代碼,所以我使用'if'來確保'value.details'不是空的(參見我更新的問題)。我的代碼是正確的嗎?或者它是'waterline'的問題嗎? – user3741665

+0

對不起,我沒有仔細注意你的'async.auto'代碼。 'updateStock'後面有函數簽名:它應該是'(cb,results)',而不是反過來。最後的回調應該是'(err,results)'。更新我的代碼以反映更改。否則看起來不錯(你對'value.details'的測試很好)。 – sgress454

+0

這是工作!謝謝。你太棒了! :) – user3741665

0

您遇到的問題是由於async.auto呼叫燒製afterCreate回調()在你的_.each裏面的第一個完整的迭代。

有很多潛在的解決方案,但無論您使用哪種解決方案,都需要每次迭代的內部包裝。然後一些方法來收集每個迭代,並一次性觸發afterCreate的回調()。