2017-02-26 74 views
0

我有以下方法異步返回值。在其餘值填充之前,return inventoryData似乎會觸發。下面是日誌:返回inventoryData承諾值返回前被觸發

enter image description here

我想等到前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; 
    }); 
} 

回答

2

JavaScript是單線程。不能使用「等待」功能。函數執行直到它返回。它只能返回可用的值或待定的承諾,稍後在數據從服務器返回時執行。

要創建承諾inventoryData,使用$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方法接受一個物體在其上的部分或全部該對象的屬性可以是承諾。它返回一個承諾,用第一個被拒絕的承諾的價值來解決個體承諾或拒絕的所有履行價值。

要使用:

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

這是設計,承諾如何工作。你需要將你的承諾鏈接到彼此(在這些地方),然後你需要從最後一個返回庫存數據,或者只是返回承諾並繼續工作。

+0

能否請你告訴我如何可以用我的代碼來完成的例子嗎? – methuselah

+1

'$ q.all'會是一個很好的開始:http://stackoverflow.com/questions/21310964/angularjs-q-all – Jorg

1

您可以使用Promise.all,它可以接受一系列承諾,並在所有傳遞的承諾已解決且能夠調用.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 
    }); 
} 
+0

如何從Promise.all中返回stockData? – methuselah