2016-02-29 21 views
0

組裝數據我有這樣

var projectPromises = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456'); 

    $q.all([projectPromises]).then(function(data) { 
    console.log(data); 
    return data[0]; 
    }).then(function(projects) { 
    var data = projects.data; 
    var promises = []; 
    var file = []; 
    for(var i = 0; i < data.length; i++){ 
     var url = 'http://myapi.com/api/v3/projects/' + data[i].id + "/owner"; 
     promises.push($http.get(url)); 

    } 

    console.log(promises); 
    $q.all(promises).then(function(user) { 
     console.log(user); 
    }, function(error) { 
     console.log("error here"); 
     console.log(error); 
    }); 

一段源代碼,讓我解釋一下我的源代碼。

首先,我將返回的項目列表中的第一API和我分配到projectPromises。獲得項目列表後,每個項目都將包含一個項目ID。我將遍歷項目列表並激發相應的http請求以獲取項目的所有者。

在那之後,我就用角q模塊推遲承諾的列表和日誌列表到控制檯

console.log(user); 

這裏並不登錄任何東西。我嘗試打印錯誤,我知道原因是並非所有項目都包含用戶列表。否則,將返回404和200,反之亦然。所以承諾列表將包含來自API都200和404的對象的回報,所以我客人,當使用q推遲的承諾,它如果對象是404,但我不知道如何解決這個問題拋出的錯誤。

我的最終目的是讓每個項目的業主,他們將被填充到一個數組。

回答

1

有沒有必要使用$q.all(),除非你有多個承諾。 $http.get()會返回一個承諾,所以您可以在該承諾上致電.then

一旦您擁有項目ID列表,您可以將其映射到一組承諾,每個承諾都有一個.catch(),以在各自請求失敗時提供回退值。

一旦你有了,你可以使用承諾數組$q.all(),然後再一個.then(),你應該都設置。

var pProjects = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456'); 

pProjects 
    .then(function (result) { 
     // map the project IDs to an array of promises for each project's owner 
     var pProjectOwners = result.data.map(function (proj) { 
      return $http 
       .get('http://myapi.com/api/v3/projects/' + proj.id + '/owner') 
       .then(function (result) { return result.data; }) 
       // fallback value to use when a request fails 
       .catch(function() { return 'no owner'; }); 
     }); 

     return $q.all(pProjectOwners); 
    }) 
    .then(function (projectOwners) { 
     console.log(projectOwners); 
    }) 
    .catch(function (error) { 
     console.error("something went wrong", error); 
    }); 

而這裏的可替代的形式與一些重構分離出操作以獲取項目的所有者:

function getProjectOwner(projectId) { 
    return $http 
     .get('http://myapi.com/api/v3/projects/' + projectId + '/owner') 
     .then(function (result) { return result.data; }) 
} 

var pProjects = $http.get('http://myapi.com/api/v3/projects?private_token=abcde123456'); 

pProjects 
    .then(function (result) { 
     // map the project IDs to an array of promises for each project's owner 
     var pProjectOwners = result.data.map(function (proj) { 
      return getProjectOwner(proj.id) 
       // fallback value to use when a request fails 
       .catch(function() { return 'no owner'; }); 
     }); 

     return $q.all(pProjectOwners); 
    }) 
    .then(function (projectOwners) { 
     console.log(projectOwners); 
    }) 
    .catch(function (error) { 
     console.error("something went wrong", error); 
    }); 
+0

瞭解了一些關於承諾從這個新的..thx – charlietfl

+0

@charlietfl很高興幫助。請記住'.then()'和'.catch()'都會創建新的承諾。它們對上游承諾沒有影響。 – JLRishe

+0

yup ..創建一個[plunker](http://plnkr.co/edit/1pecB8iq8uaN8SvMljme?p=preview)看到這個更好 – charlietfl

0

你讓你的承諾過於複雜。你可以直接綁定到你的http調用來與$ http返回的promise進行交互。

$http.get("http://myapi.com/api/v3/projects?private_token=abcde123456").then(function (results) { 
    // projects will be your array of projects 
    var projects = results.data; 

    // Use native Array for each to get reference to every object in array 
    projects.forEach(function (project) { 
    $http.get("http://myapi.com/api/v3/projects/' + project.id + "/owner").then(function (results) { 
     var data = results.data; 
     console.log(data); // This will log your owner 
    }); 
    }) 
}); 

你或許應該只是你的巢用返回的項目業主JSON限制這些外來的HTTP請求,但是這是服務器端架構的問題。

+0

這不會做同樣的事情。它不允許所有請求在繼續之前完成 – charlietfl

+0

@charlietfl:同意,這不回答我的問題。我希望所有任務都能讓項目所有者異步運行,然後在準備好時獲得所有者的完整列表。 – xtiger

+0

對不起,在問題的任何地方都沒有看到那個約束。我的回答基於措辭回答了原來的問題。 –