递归遍历Promises [英] Iterating over Promises recursively

查看:68
本文介绍了递归遍历Promises的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个REST API接口,该接口仅使我获得一些信息的第一层.

I have an REST API interface which only gets me the first level of some information.

例如,我想收集组.每个组都可以有子组.因此,例如组1"具有子组组A"和组B".组A"具有子组"GroupX".依此类推.

So for example I want to collect groups. Every Group can have subgroups. So for example "Group 1" has the Subgroups "Group A" and "Group B". "Group A" has the Subgroup "GroupX". And so on.

但是API仅为我提供了组名称的第一级组.因此,我将"Group 1"传递给API,并返回"Group A"和"Group B".要获得组A的子组,我需要再次调用API.但是我不知道它将有多少次迭代.

But the API only gives me the first level of Groups for a group name. So I pass "Group 1" to the API and it returns "Group A" and "Group B". To get the supgroups of Group A, I need to call the API again. But i don't know how many iterations of this it will have.

所以我考虑过使用递归,但距离还很远.

So I thought about using recursion but I haven't come far.

到目前为止,我的代码:

So far my Code:

getGroupChildren(group:string){ return this restService.getGroupChildren(group)}

getGroups():Promise<any>{
  let collection:string[] = [];
    return this.getGroupChildren("Group A").then((result)=> {
      if(result.data.length !==0){
         return this.getGroupChildren(data[0].groupName);
      }
    });
}

现在,这只会返回我第一个元素的第一个Supgroups.

Now this will only return me the first Supgroups of the first element.

我怎么才能做到,无论有多少个Supgroup,总能找到它?也许使用Observables很好吗?

How can I accomplish it will always find every Supgroup no matter how many? Maybe is it good to use Observables?

这里是一个API调用的示例结构:

Here an example structure of one API call:

{  "groupName" : "Group_1",  "children" : ["Group_A", "Group_B"]}

推荐答案

您可以使用 Observable

getGroups(group: string) {

    return this.http.get(`/group/{group}`).flatMap(response => {
        if (response.children.length === 0) { // you hit a leaf, stop recursion here
             return Observable.of(response);
        } else { // there are more levels to go deeper
             return this.getGroups(response.children[0].groupName);
        }
    });
}

编辑使用Promise

Edit Using Promise

假设您使用 GroupService 返回数据而不是 HttpClient .您可以使用 fromPromise 运算符将 Promise 转换为 Observable .

Let's say you use a GroupService which returns the data instead of HttpClient. You can convert a Promise to an Observable with fromPromise operator.

getGroups(group: string) {

    return Observable.fromPromise(this.groupService.get(group)).flatMap(response => {
        if (response.children.length === 0) { // you hit a leaf, stop recursion here
             return Observable.of(response);
        } else { // there are more levels to go deeper
             return this.getGroups(response.children[0].groupName);
        }
    });
}

编辑2 使用此服务

让我们看一下您的示例.您有以下json

Let's take a look at your example. You have following json

{
    "groupName": "Group_1", 
    "children" : ["Group_A", "Group_B"]
}

在组件文件中,您按以下方式调用服务

In your component file, you call the service as follows

...
this.recursiveGroupService.getGroups("Group_1")
    .subscribe(response => {
        // at this point response will be `Group_A`
    })

编辑3 获取整个对象

这次,我们将使用 forkJoin 并为所有子代调用 getGroups 并将结果收集在 children 数组中.

This time we'll use forkJoin and call getGroups for all of the children and collect the results in a children array.

注意:我尚未亲自测试此代码.它可能包含一些错误.如果有的话,让我知道.

Note: I haven't tested this code myself. It may contains some error. If it has, let me know.

import { forkJoin, of } from 'rxjs';
import { map } from 'rxjs/operators';

getGroups(group: string) {
    let retVal;
    return Observable.fromPromise(this.groupService.get(group)).flatMap(response => {
        retVal = {
             groupName: response.groupName
        };
        if (response.children.length === 0) { // you hit a leaf, stop recursion here
             return of(retVal);
        } else { // there are more levels to go deeper
             // this will create list of observable for each child
             const children$ = response.children.map(
                       child => this.getGroups(child)); 
             // forkJoin will execute these observables in parallel
             return forkJoin(children$).pipe(
                  map(results => {
                      // results is an array containing children data
                      retVal.children = results;

                      return retVal;
                  })
             );
         }
    });
}

这篇关于递归遍历Promises的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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