我有一段代码,如下所示

getInformations().subscribe(
    informations => {
        let subs = [];
        for (const information of informations) {
            subs.push(getOtherDetails(information.id));
        }
        forkJoin(subs).subscribe(response => {
           //How can I Associate Information Id With The Response
            howToAssociateIdWithResponse();
     }}
);

Situation-我想将第二个电话的响应与第一个电话的ID绑定,但我遇到了问题.

Attempted-我try 了以下方法,但似乎出错了

let subs: {[x:number]: Observable<any>}[] = [];
subs.push({information.id: getOtherDetails(info.id)}) 

但是当我订阅的时候,我收到了一个错误,说是You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.


Update - 1在遵循@BizzyBob建议之后,代码如下所示,但我的另一个逻辑在订阅完成其作业(job)之前运行.这就是我的意思

async ngOnChanges(){
    await getData(); //How to make sure below method only executes when this is really done.
    await useInformationReceivedFromgetData(); 
}
async getData(){
  getInformations().subscribe(
    informations => {
      let subs = [];
      for (const information of informations) {
         subs.push(getOtherDetails(information.id).pipe(
            map(data => ({ id: information.id, data })) // <---
         ));
      }
      forkJoin(subs).subscribe(objects => {           
         objects.forEach(({id, data}) => { /* saved to an arrray */ });
      });
   }

);
}

推荐答案

您可以使每个"getOtherDetail可观测"发送一个带有id和响应data的对象:

getInformations().subscribe(
   informations => {
      let subs = [];
      for (const information of informations) {
         subs.push(getOtherDetails(information.id).pipe(
            map(data => ({ id: information.id, data })) // <---
         ));
      }
      forkJoin(subs).subscribe(objects => {           
         objects.forEach(({id, data}) => { /* use id and data here */ });
      });
   }
);

请注意,您可以使用.map()来简化代码,而不是创建一个subs数组并将其暂停:

getInformations().subscribe(
   informations => {
      const subs = informations.map(
         ({id}) => getOtherDetails(id).pipe(map(data => ({ id, data })))
      );
      forkJoin(subs).subscribe(responses => {           
         responses.forEach(({id, data}) => { /* use id and data here */ });
      });
   }
);

此外,将订阅放在订阅中也不是什么好消息.你最好使用Higher Order Mapping Operator,它将为你处理"内部订阅".在这种情况下,我们可以使用switchMap来处理对您的forkJoin观察值的订阅/取消订阅:

getInformations().pipe(
   map(informations => informations.map(
      ({id}) => getOtherDetails(id).pipe(map(response => ({ id, data })))
   ),
   switchMap(requests => forkJoin(requests))
).subscribe(
   responses => responses.forEach(({id, data}) => { ... })
);

Javascript相关问答推荐

如何从JavaScript中的公共方法调用私有方法?

错误:找不到react-redux上下文值;请确保该组件包装在React原生Expo应用程序中的提供者中

如何使用JavaScript向html元素添加样式

如何使用CSS和JavaScript创建粘性、凝聚力的形状到形状(容器)变形?

为什么JavaScript双边字符串文字插值不是二次的?

为什么getRecord()会因为与_logger相关的错误而失败?(使用Hedera SDK)

为什么从liveWire info js代码传递数组我出现错误?

从实时数据库(Firebase)上的子类别读取数据

过滤对象数组并动态将属性放入新数组

jQuery提交按钮重新加载页面,即使在WordPress中使用preventDefault()

无法在nextjs应用程序中通过id从mongoDB删除'

TypeScript索引签名模板限制

有没有可能使滑动img动画以更快的速度连续?

无法检测卡片重叠状态的问题

在SHINY R中的嵌套模块中,不能使用Java代码

删除加载页面时不存在的元素(JavaScript)

在单击按钮时生成多个表单时的处理状态

如何在Java脚本中并行运行for或任意循环的每次迭代

Chart.js Hover线条在鼠标离开时不会消失

我如何才能获得价值观察家&对象&S的价值?