Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 等待递归forkJoin_Angular_Typescript_Http_Async Await_Rxjs - Fatal编程技术网

Angular 等待递归forkJoin

Angular 等待递归forkJoin,angular,typescript,http,async-await,rxjs,Angular,Typescript,Http,Async Await,Rxjs,试图找出我可以在递归forkJoin中等待所有http调用吗。如何等待forkJoin中的所有http调用并接收最终结果 目前,我有如下几点 public myMethod(urls: string[]) { ... return forkJoin(observables) .pipe(map(() => { if (json.urls !== 0) { return this.myMethod(json.urls);

试图找出我可以在递归forkJoin中等待所有http调用吗。如何等待forkJoin中的所有http调用并接收最终结果

目前,我有如下几点

public myMethod(urls: string[]) {

...

return forkJoin(observables)
        .pipe(map(() => {
          if (json.urls !== 0) {
            return this.myMethod(json.urls);
          }
        }),   catchError((err) => {
          console.log(err);
          return of(null);
        })
        );
}

And then I subscribe ...

public mainMehtod(){
  return this.myMethod([json]).pipe(map(() => {
      ...some stuff here. But I need here the final result from the finished recursion
    }));
编辑


我找到的解决方案是,在递归中收集所有的可观察对象,然后调用forkjoin。

有一个
展开操作符,它解决了您的问题

以下是您应该如何使用它:

import{fromEvent,of,forkJoin,EMPTY}来自'rxjs';
从“rxjs/operators”导入{expand,delay,map,reduce,last};
常量数据库:元素[]=[
{id:'1',childId:'3'},
{id:'two',childId:'four'},
{id:'3',childId:'5'},
{id:'4',childId:'6'},
{id:'five',childId:null},
{id:'six',childId:null}
];
main方法(['one','two'])。订阅(值=>{
log(value.map(e=>e.id));
})
函数main方法(ID:字符串[]){
返回forkJoin(id.map(id=>getElementById(id)).pipe(
展开(值=>{
if(values.some(el=>el.childId)){
返回forkJoin(值)
.filter(v=>v.childId)
.map(el=>getElementById(el.childId))
)
}
返回空;
}),
last()//如果只希望最后一次发射,请使用此选项。小心,如果没有传递值,last将抛出错误
//reduce((acc,values)=>acc.concat(values),[])//如果您想要所有东西,请使用此选项
)
}
函数getElementById(id:string){
返回(DATABASE.find(el=>el.id==id)).pipe(
延迟(1000)
)
}
接口元素{id:string,childId:string | null}

工作示例

展开
是一个很好的方法。使用提供的代码很难做到精确,但它看起来是这样的:

private _myMethod(urls: string[]) {

  ...

  return forkJoin(observables).pipe(
    catchError(err => {
      console.log(err)
      return of(null)
    })
  )
}

public myMethod(urls: string[]) {
  return this._myMethod(urls).pipe(
    // expand will feed the value of outter observable to start, and then call this function recursively with the result of subsequent calls inside expand
    expand(json => {
      if (json.urls.length) {
        // expand calls itself recursively
        return this._myMethod(json.urls);
      }
      return EMPTY; // break
    }),
    // expand emits outter result and then results of recursion one by one. how you collect this is up to you
    // reduce is an option to collect all values in an array like this (like a forkJoin of your forkJoins)
    // reduce((acc, val) => acc.concat([val]), []) 
    // last is an option if you only want the last recursive call (or first if none from recursion)
    // last()
    // or omit these entirely if you want the results one by one.
  )
}

什么是递归?
expand
可以用于递归调用,但是需要更多关于此函数的详细信息,以便为您的特定情况提供一个工作示例这是
expand
的典型用法。。。通常你不会在
expand
内部递归,因为
expand
会为你递归。@bryan60嗯,你说得对,更新了我的答案,只在expand内部发出请求。很酷,你已经注意到了,我已经将它与外部递归一起使用了一段时间,它实际上是有效的