角平行相结合,并与$ http.then()和$ q.all链接请求() [英] Angular combining parallel and chained requests with $http.then() and $q.all()
问题描述
我有一个相当复杂的一套API调用来使,我试图做它作为优雅和高性能成为可能。我知道如何使用 $ HTTP
服务承诺API连锁要求,以及如何使用 $ Q
服务,使并行请求。但对于这个特定的API的工作流程,我需要做两件事。
下面是高层次的API流的例子:
-
/狗/< dog_id>
-
/品种/< breed_id>
-
/食品/< food_id>
-
-
-
/ CAT /<&CAT_ID GT;
-
/火鸡/< turkey_id>
-
/鱼/< fish_id>
请求的第一层都具有已知的IDS。然而,< breed_id>
,使 /品种
呼叫必须被解析所需的 /狗
响应和< food_id>
,使要求/食品
通话必须从 /品种
响应进行解析。因此, /狗
, /品种
和 /食品
所有需要进行链接。然而 /猫
, /土耳其
和 /鱼
CAN并行进行与整个 /狗
链。
我现在得到什么(它是工作的罚款)是两个单独的请求集。如何在这个流程改进?有没有办法给两个堆栈以导致的一个承诺,执行的方式组合。然后()
?
VAR dogId ='472053',
CATID ='840385',
turkeyId ='240987',
fishId ='510412';VAR的myData = {};VAR firstSetComplete =假,
secondSetComplete =假,
returnData =功能(){
如果(firstSetComplete&安培;&安培; secondSetComplete){
的console.log(myData.dog,myData.dog);
的console.log(myData.dog.breed,myData.dog.breed);
的console.log(myData.dog.food,myData.dog.food);
的console.log(myData.cat,myData.cat);
的console.log(myData.turkey,myData.turkey);
的console.log(myData.fish,myData.fish);
}
};//首先调用集
$ http.get('http://example.com/dog/'+ dogId)
。然后(功能(响应){
myData.dog = response.data;
返回$ http.get('http://example.com/breed/'+ response.data.breed_id);
})
。然后(功能(响应){
myData.dog.breed = response.data;
返回$ http.get('http://example.com/food/'+ response.data.food_id);
})
。然后(功能(响应){
myData.dog.food = response.data; firstSetComplete = TRUE;
returnData();
});//第二调用集
$ q.all([
$ http.get('http://example.com/cat/'+ CATID)
$ http.get('http://example.com/turkey/'+ turkeyId)
$ http.get('http://example.com/fish/'+ fishId)
])
。然后(函数(响应){
myData.cat =响应[0]。数据;
myData.turkey =反应[1]。数据;
myData.fish =反应[2]。数据; secondSetComplete = TRUE;
returnData();
});
您可以在第一链通过像这样:
$ q.all([
$ http.get('http://example.com/cat/'+ CATID)
$ http.get('http://example.com/turkey/'+ turkeyId)
$ http.get('http://example.com/fish/'+ fishId)
$ http.get('http://example.com/dog/'+ dogId)
。然后(功能(响应){
myData.dog = response.data;
返回$ http.get('http://example.com/breed/'+ response.data.breed_id);
})
。然后(功能(响应){
myData.dog.breed = response.data;
返回$ http.get('http://example.com/food/'+ response.data.food_id);
})
。然后(功能(响应){
myData.dog.food = response.data;
返回MYDATA的;
})
])
。然后(函数(响应){
myData.cat =响应[0]。数据;
myData.turkey =反应[1]。数据;
myData.fish =反应[2]。数据; secondSetComplete = TRUE;
returnData();
});
这狗诺言大型连锁结束返回时最后不是被调用,它与无论是从最后的最后返回决定,解决了一个承诺。因此,没有任何理由,你不能窝在你的 $ q.all()
电话。
I have a rather complicated set of API calls to make and I'm attempting to do it as elegantly and performant as possible. I understand how to use the promise api of the $http
service to chain requests, and how to use the $q
service to make requests in parallel. But for this specific API workflow I need to do both.
Here is an example of the high-level API flow:
/dog/<dog_id>
/breed/<breed_id>
/food/<food_id>
/cat/<cat_id>
/turkey/<turkey_id>
/fish/<fish_id>
The first tier of requests all have known ids. However the <breed_id>
required to make the /breed
call must be parsed from the /dog
response, and the <food_id>
required to make the /food
call must be parsed from the /breed
response. So /dog
, /breed
, and /food
all need to be chained. However /cat
, /turkey
, and /fish
can be made in parallel with the entire /dog
chain.
What I've got now (and it is working fine) are two separate sets of requests. How do I improve on this flow? Is there a way to combine the two stacks in a way that results in a single promise execution of .then()
?
var dogId = '472053',
catId = '840385',
turkeyId = '240987',
fishId = '510412';
var myData = {};
var firstSetComplete = false,
secondSetComplete = false,
returnData = function() {
if (firstSetComplete && secondSetComplete) {
console.log("myData.dog", myData.dog);
console.log("myData.dog.breed", myData.dog.breed);
console.log("myData.dog.food", myData.dog.food);
console.log("myData.cat", myData.cat);
console.log("myData.turkey", myData.turkey);
console.log("myData.fish", myData.fish);
}
};
// first call set
$http.get('http://example.com/dog/' + dogId)
.then(function(response) {
myData.dog = response.data;
return $http.get('http://example.com/breed/' + response.data.breed_id);
})
.then(function(response) {
myData.dog.breed = response.data;
return $http.get('http://example.com/food/' + response.data.food_id);
})
.then(function(response) {
myData.dog.food = response.data;
firstSetComplete = true;
returnData();
});
// second call set
$q.all([
$http.get('http://example.com/cat/' + catId),
$http.get('http://example.com/turkey/' + turkeyId),
$http.get('http://example.com/fish/' + fishId)
])
.then(function(responses) {
myData.cat = responses[0].data;
myData.turkey = responses[1].data;
myData.fish = responses[2].data;
secondSetComplete = true;
returnData();
});
You can pass in the first chain like so:
$q.all([
$http.get('http://example.com/cat/' + catId),
$http.get('http://example.com/turkey/' + turkeyId),
$http.get('http://example.com/fish/' + fishId),
$http.get('http://example.com/dog/' + dogId)
.then(function(response) {
myData.dog = response.data;
return $http.get('http://example.com/breed/' + response.data.breed_id);
})
.then(function(response) {
myData.dog.breed = response.data;
return $http.get('http://example.com/food/' + response.data.food_id);
})
.then(function(response) {
myData.dog.food = response.data;
return myData;
})
])
.then(function(responses) {
myData.cat = responses[0].data;
myData.turkey = responses[1].data;
myData.fish = responses[2].data;
secondSetComplete = true;
returnData();
});
That big chain of promises for dogs ends up returning a single promise that is resolved when the last than is called and it's resolved with whatever is returned from that final end. So there is no reason that you can't nest it in your $q.all()
call.
这篇关于角平行相结合,并与$ http.then()和$ q.all链接请求()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!