【问题标题】:return inventoryData is fired before promise values returnreturn inventoryData 在承诺值返回之前被触发
【发布时间】:2017-07-17 10:38:17
【问题描述】:

我有以下异步返回值的方法。 return inventoryData 似乎在填充其余值之前触发。这是日志:

我想等到所有值都被检索到,然后再触发return inventoryData。我该怎么做?

function checkInventoryUrl(url, size, code) {
  var inventoryData = {};

  return $http.get(url).then(function(response) {
    var html = response.data;

    // returns value instantly
    inventoryData.url = url;

    // parses html, takes a few seconds to return value
    inventoryData.name = getProductName(html);
    inventoryData.price = getPrice(html);

    // returns promise
    getProductQty(html, size).then(function(result) {
      if(result) {
        inventoryData.qtyAvailable = result;
        console.log(inventoryData);
      }
    });

    // returns promise
    getProductMaxOrder(html, size).then(function(result) {
      if(result) {
        inventoryData.maxOrder = result;
        console.log(inventoryData);
      }
    });

    // returns promise
    getProductSize(html, size).then(function(result) {
      if(result) {
        inventoryData.size = result;
        console.log(inventoryData);
      }
    });

    // fired straight away returns empty object
    return inventoryData;
  });
}

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    这是设计使然,以及 promise 的工作方式。您需要将您的 Promise 相互链接起来(在 thens 中),然后您需要从最后一个返回 inventoryData,或者只返回 Promise 并继续使用它。

    【讨论】:

    【解决方案2】:

    您可以使用Promise.all,它可以接受一组promise,并且当所有传递的promise 都已解决时,可以调用.then 方法调用。

    一个例子:

    function checkInventoryUrl(url, size, code) { 
      var inventoryData = {}; 
      ....
      .... 
      inventoryData.url = url; // parses html, takes a few seconds to return value 
      inventoryData.name = getProductName(html); 
      var p0 = inventoryData.price = getPrice(html); // returns promise 
      var p1 = getProductQty(html, size); 
      var p2 = getProductMaxOrder(html, size);
      var p3 = getProductSize(html, size);
    
      Promise.all([p0, p1, p2, p3,])
        .then(function(values){
        // Called when all promises passed in resolve
        });
    }
    

    【讨论】:

    • 如何从 Promise.all 中返回 stockData?
    【解决方案3】:

    JavaScript 是单线程的。不能使函数“等待”。一个函数一直执行直到它返回。它只能返回可用的值或 pending 承诺,该承诺稍后会在数据从服务器返回时实现。

    要为inventoryData 创建一个promise,请使用$q.all

    function checkInventoryUrl(url, size, code) {
      var inventoryData = {};
    
      return $http.get(url).then(function(response) {
        var html = response.data;
    
        // returns value instantly
        inventoryData.url = url;
    
        // parses html, takes a few seconds to return value
        inventoryData.name = getProductName(html);
        inventoryData.price = getPrice(html);
    
        // returns promise
        inventory.qtyAvailable = getProductQty(html, size);
    
        // returns promise
        inventoryData.maxOrder = getProductMaxOrder(html, size);
    
        // returns promise
        inventoryData.size = getProductSize(html, size);
    
        //RETURN composite promise
        return $q.all(inventoryData);
      });
    }
    

    $q.all 方法接受一个对象,该对象的部分或全部属性可能是 Promise。它返回一个 Promise,该 Promise 使用单个 Promise 的所有已实现值解析已完成,或者以第一个被拒绝的 Promise 的值拒绝。

    使用方法:

     checkInventory(url, size, code).then(function (inventoryData) {
         console.log(inventoryData);
     }).catch(function(errorResponse) {
         throw errorResponse;
     }); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 2015-03-17
      相关资源
      最近更新 更多