【问题标题】:Result of a promise inside of forEachforEach 中承诺的结果
【发布时间】:2016-09-17 09:46:03
【问题描述】:

我正在尝试使用承诺 (Q) 重写我的一个项目的代码。 我不知道如何在 foreach 循环中获取一系列承诺的结果:

var resProducts = [];
products.forEach(currProduct) {
     Stock.saveNewStock(currProduct)
        .then(function(res1) {
            Product.saveNewProduct(currProduct)
               .then(function(res2) {
                  resProducts.push(res2);
                  Product.addStockToProduct(res1,res2)
               })
         })
         .catch(function(err) {
             console.log(err)
         })
});
console.log(resProducts);

我看到每次日志都标记一个空数组,那么我该如何解决呢?

【问题讨论】:

  • 附带说明:javascript 是同步的,打印数组值的函数调用位于异步块之外,这使得它几乎立即运行。可能值得反思! :)

标签: javascript node.js promise


【解决方案1】:

你应该总是return all promises,而你在这里的几个地方忘记了。

如果你可以使用 => 箭头函数,那么这些函数会隐式返回,这样可以避免忘记。

使用map 代替忽略返回值的forEach 并将结果返回到数组中。这也可以并行工作:

Promise.all(products.map(product => Stock.saveNewStock(product)
  .then(res1 => Product.saveNewProduct(product)
    .then(res2 => Product.addStockToProduct(res1, res2)
      .then(() => res2))))
.then(resProducts => console.log(resProducts))
.catch(err => console.error(err));

这里的嵌套是有意的,将res1res2 一起访问。

【讨论】:

    【解决方案2】:

    这个怎么样?

    // Define iterator function
    function doThingsWithProducts(productsLeft, resProducts) {
        if (productsLeft.length === 0) { return resProducts }
        else {
            var currProduct = productsLeft.shift(), res1, res2;
            return Stock.saveNewStock(currProduct)
            .then(function(res) {
                res1 = res;
                return Product.saveNewProduct(currProduct)
            })
            .then(function(res) {
                res2 = res;
                resProducts.push(res2);
                return Product.addStockToProduct(res1, res2)
            })
            .then(function() {
                return doThingsWithProducts(productsLeft, resProducts)
            })
            .catch(function(err) {
                console.log(err);
            })
        }
    }
    
    // resProducts is available in the result of the function
    doThingsWithProducts(products, [])
    .then(function(resProducts) {
        console.log(resProducts);
    })
    

    【讨论】:

      【解决方案3】:

      你需要这样的东西吗?

      var defer = $q.defer();
                  var promises = [];
                  var resProducts = [];
                  var errorCallback = function (e) {
      
                    defer.reject();
                  };
      
                 products.forEach(currProduct) {
      
                      promises.push(function () {
                          Stock.saveNewStock(currProduct)
                              .then(function(res1) {
                                  return Product.saveNewProduct(currProduct)
                              .then(function(res2) {
                                  resProducts.push(res2);
                                  Product.addStockToProduct(res1,res2)
                         })
                   })
                   .catch(function(err) {
                       console.log(err)
                   })
                      }
      
      
                      );
                    }
      
                  });
                  return $q.all(promises);
      

      【讨论】:

        【解决方案4】:

        Array.map()Q.all() 结合使用

        var resProducts = [];
        
        Q.all(products.map(function (currProduct) {
                // Return promise that Q.all() can resolve.
                return Stock.saveNewStock(currProduct)
                    .then(function (res1) {
                        // Make sure you always return promises when they
                        // are in a chain so  the chain will work correctly.
                        return Product.saveNewProduct(currProduct)
                            .then(function (res2) {
                                resProducts.push(res2);
                                return Product.addStockToProduct(res1, res2)
                            })
                    })
            }))
            .then(function (products) {
                // Products here is the array of resolved promises.
        
                // and here your array will be full.
                console.log(resProducts);
            })
            .catch(function (err) {
                console.log(err)
            });
        

        【讨论】:

          猜你喜欢
          • 2017-10-18
          • 1970-01-01
          • 2019-05-03
          • 2017-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-19
          • 2019-06-01
          相关资源
          最近更新 更多