SAILS 0.10: проблема с синхронизацией и обещанием при сохранении в базу данных

#promise #sails.js #waterline #async.js #sails-mongo

#обещание #sails.js #ватерлиния #async.js #паруса-монго #sails-mongo

Вопрос:

Кажется, у меня проблема с асинхронностью по обещанию. Я тестировал sails-mysql, sails-mongo, sails-postgres версии 0.10-rc-XX, и проблема в том, что это произошло. Но когда я использую sails-disk, проблем нет. Посмотрите мой комментарий ниже

 var storeInvoiceDetail = function( detail ) {
  return function( cb ) {
    cb(null, detail);
  };
}

var getPreviousDetail = ['storeInvoiceDetail', function( cb, results ) {
  var invoiceDetail = results.storeInvoiceDetail;

  PreviousDetail
    .findOne({
      invoice: invoiceDetail.invoice,
      product: invoiceDetail.product.id
    })
    .sort('createdAt desc')
    .exec(cb);
}];

var createPreviousDetail = ['storeInvoiceDetail', function( cb, results ) {
  var invoiceDetail = results.storeInvoiceDetail;

  PreviousDetail
    .create({
      invoice: invoiceDetail.invoice,
      product: invoiceDetail.product.id,
      quantity: invoiceDetail.quantity
    })
    .exec(cb);
}];

var getStockDifference = ['storeInvoiceDetail', 'getPreviousDetail', function( cb, results ) {
  var difference = results.storeInvoiceDetail.quantity - results.getPreviousDetail.quantity;

  cb(null, difference);
}];

// see here
var updateProductStock = ['getPreviousDetail', 'getStockDifference', function( cb, results ) {
  Product
    .findOne(results.getPreviousDetail.product)
    .then(function(product) {
      // imagine the value of 'results.getStockDifference' is 5
      product.stock  = results.getStockDifference;
      product.save();

      // when I do log, the output is: 5, but this value is not updated to database
      // It seems 'product.save()' at above is not called
      // maybe this code have issues with 'async' amp; 'promise'
      // anybody know how to correct this?
      console.log(product.stock);
      cb(null, product.stock);
    });
}];

exports.updateProductStock = function (details) {
  var beforeModifyProductStock = {};

  async.each(details, function( detail, callback ) {
    beforeModifyProductStock = {
      storeInvoiceDetail: storeInvoiceDetail(detail),
      getPreviousDetail: getPreviousDetail,
      createPreviousDetail: createPreviousDetail,
      getStockDifference: getStockDifference,
      updateProductStock: updateProductStock
    };

    async.auto(beforeModifyProductStock, function( err, results ) {
      console.log('now latest stock is '   results.updateProductStock);
      callback();
    });

  }, function (err) {
    // no action
  });
}
  

Комментарии:

1. Почему вы используете async здесь? У вас уже есть намного более мощные обещания в вашем коде…

2. @Benjamin Потому что я хочу повторить переменную ‘details’ и передать ее в функцию ‘updateProductStock’. Это асинхронно, поэтому я не могу использовать _.each . Не возражаете, если вы приведете мне пример, в котором используется только ‘promise’?

Ответ №1:

.save() это асинхронный метод. Перепишите вашу updateProductStock функцию как:

 var updateProductStock = ['getPreviousDetail', 'getStockDifference', function( cb, results ) {
  Product
    .findOne(results.getPreviousDetail.product)
    .then(function(product) {
      product.stock  = results.getStockDifference;
      // Note the callback argument to .save()
      product.save(function(err, product) {
          console.log(product.stock);
          cb(err, product.stock);
      });    
    });
}];
  

и с вами все должно быть в порядке.