Javascript 变换可观测<;字符串[]>;可观察<;数据类型[]>;

Javascript 变换可观测<;字符串[]>;可观察<;数据类型[]>;,javascript,angular,rxjs,pipe,observable,Javascript,Angular,Rxjs,Pipe,Observable,我有一个api,在给定原始id(一对多)的情况下,它返回id的数组。我需要对每个ID发出http请求,以从api中获取相关数据。我不知道如何将可观察的映射到可观察的 我希望保持原始的可观察性,并尽可能使用操作符获得期望的结果 在这种情况下,map操作符不起作用,因为在可观察项中只有数组 下面是一些与我尝试的实现类似的示例代码 getid=(originalId:string)=>{ 返回此.http.get(url); } getDataFromIds=(originalId:string):可

我有一个api,在给定原始id(一对多)的情况下,它返回id的
数组
。我需要对每个ID发出http请求,以从api中获取相关数据。我不知道如何将
可观察的
映射到
可观察的

我希望保持原始的可观察性,并尽可能使用操作符获得期望的结果

在这种情况下,
map
操作符不起作用,因为在可观察项中只有数组

下面是一些与我尝试的实现类似的示例代码

getid=(originalId:string)=>{
返回此.http.get(url);
}
getDataFromIds=(originalId:string):可观察=>{
const ids$=this.getIds(originalId);
//对数组中的每个项进行http调用。
结果=ids$.pipe();
返回结果;
}
您可以尝试以下方法:

ids$.pipe(
  switchMap(ids => //you can swap switchMap with any *Map operator: https://www.learnrxjs.io/operators/transformation/
    forkJoin(...ids.map(id => //you swap forkJoin with any comb. operator: https://www.learnrxjs.io/operators/combination/
      from(Promise.resolve({ id })).pipe(
        map(res => res.id),
        catchError(err => of(err)))))));
从中导入的
,forkJoin
应该来自
rxjs
,而其他所有内容都是从
rxjs/操作符导入的

catchError
将捕获任何抛出的未处理错误

演示:

这是switchMap操作符的一个典型用例,forkjoin操作符是您的内部可观察对象

getIds = (originalId: string) => {
 return this.http.get<string[]>(url);
}

getDataFromIds = (originalId: string): Observable<DataType[]> => {
  const ids$ = this.getIds(originalId);
  // Make http calls for each of the items in the array.
  result = ids$.pipe(switchmap(ids => forkJoin(ids.map(id => this.getId(id))));
  // map the array of ids into an array of Observable<DataType>, forkjoin them and switch into it.

  return result;
}
getid=(originalId:string)=>{
返回此.http.get(url);
}
getDataFromIds=(originalId:string):可观察=>{
const ids$=this.getIds(originalId);
//对数组中的每个项进行http调用。
result=ids$.pipe(switchmap(ids=>forkJoin(ids.map(id=>this.getId(id)));
//将ID数组映射到可观察的数组中,将它们连接起来并切换到其中。
返回结果;
}

这是假设getId()调用将产生一个字符串ID列表,并且您有一些getId()函数,它接受一个字符串ID并返回一个可观察的数据类型

,粗略地说,您希望切换到forkJoin。但是,您没有描述如果其中一个请求失败会发生什么。很好的一点。我没有想到http失败的可能性。如果请求失败,它应该继续到下一个ID,而不是他响应失败。这是zip的一个不好的用例,因为它是一个非终止的可观察对象,通常在这种情况下,您希望使用完整的可观察对象(forkJoin)使用zip可能需要不必要的订阅CurruffFokJoin有一个缺点,它需要被观察到的完成以传播最终结果,这可以阻止流,并且你应该真正考虑使用不同的操作符的权衡。每种情况都是不同的。有疑问的是,这意味着它们是完整的,并且forkJoin是这个用例的正确操作符。除了我使用了
combineAll()
操作符之外,我们以相同的结果结束。与
forkJoin()相比,我的方法有什么缺点吗
?在这个用例中是相同的。细微的区别是,
forkJoin
只会发出一个值:在所有内部观测值完成后,最终的结果数组。
combineAll
可能会发出多个值:当每个内部观测值产生一个值时发出一次,当任何内部观测值产生时发出一次一个附加值。由于您的内部观察值都在1个值之后终止,因此这种区别变得没有意义。我会使用
forkJoin
,因为它在语义上更为正确。这里的结果相同。我更喜欢forkJoin,因为通常情况下,CombineTest的期望是内部流具有多个发射,而forkJoin是声明性的,表示您期望单次发射。