角平行相结合,并与$ http.then()和$ q.all链接请求() [英] Angular combining parallel and chained requests with $http.then() and $q.all()

查看:129
本文介绍了角平行相结合,并与$ http.then()和$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆