如何使用angular 6和RxJs 6从forkJoin的订阅返回值?

如何使用angular 6和RxJs 6从forkJoin的订阅返回值?,angular,rxjs6,Angular,Rxjs6,所以我需要在订阅结束后返回end。我想我们必须把这个函数减半 重要提示:返回保存(有效负载)需要一个函数来返回从forkjoin组合而成的可观测值,然后从其他地方订阅它 payload.formData.steps[newMediaInStepIndex[i]].media[0].id = media.id; private saveToServer(有效负载){ (payload.formData.steps).forEach((步骤:步骤,步骤索引:编号)=>{ const media:

所以我需要在订阅结束后返回end。我想我们必须把这个函数减半


重要提示:返回保存(有效负载)

需要一个函数来返回从
forkjoin
组合而成的可观测值,然后从其他地方订阅它

payload.formData.steps[newMediaInStepIndex[i]].media[0].id  = media.id;
private saveToServer(有效负载){
(payload.formData.steps).forEach((步骤:步骤,步骤索引:编号)=>{
const media:Observable=this.createOneMedia(步骤);
如果(媒体!==未定义){
新媒体。推送(媒体);
newMediaInStepIndex.push(步进索引);
}
});
返回forkJoin(新媒体)
}
专用存储(有效负载){
这个.saveToServer(有效负载).subscribe(媒体=>{
medias.forEach((media,i)=>{
console.log('在步骤'+newMediaInStepIndex[i]中使用id:'+Media.id+'创建的媒体];
payload.formData.steps[newMediaInStepIndex[i]].media[0].id=media.id;
//叫这里
这个.createRecipe(有效载荷);
});
}); 
}

订阅方法有3个参数函数

1)
next()
,您已经使用过
2)
error()
,而您没有
3)
complete()
,在流完成后运行。

因此,您可以在完整回调中添加createRecipe,如下所示:

private saveToServer(payload) {

  (payload.formData.steps).forEach((step: Step, stepIndex: number) => {
    const media: Observable<Media> = this.createOneMedia(step);
    if (media !== undefined) {
      newMedias.push(media);
      newMediaInStepIndex.push(stepIndex);
    }
  });

  return forkJoin(newMedias) 
}


private save(payload) { 

  this.saveToServer(payload).subscribe(medias => {
    medias.forEach((media, i) => {
      console.log('Media created with id: ' + media.id + ' in step ' + newMediaInStepIndex[i]);
      payload.formData.steps[newMediaInStepIndex[i]].media[0].id  = media.id;

      //call it here
      this.createRecipe(payload);
    });
  }); 
}
这将在加载所有有效负载时调用createRecipe方法(一旦解析了newMedias数组中的所有可观察对象)


希望这能有所帮助。

我的解决方案到此为止了吗:

forkJoin(newMedias).subscribe(medias => {
    medias.forEach((media, i) => {
      console.log('Media created with id: ' + media.id + ' in step ' + newMediaInStepIndex[i]);
      payload.formData.steps[newMediaInStepIndex[i]].media[0].id  = media.id;
    });
  },
err => {},
() => {
    this.createRecipe(payload);
});
private save(p):可观察{
const payload=JSON.parse(JSON.stringify(p));
const-newMedias:Observable[]=[];
const newMediaInStepIndex:number[]=[];
(payload.formData.steps).forEach((步骤:步骤,步骤索引:编号)=>{
const media:Observable=this.createOneMedia(步骤);
如果(媒体!==未定义){
新媒体。推送(媒体);
newMediaInStepIndex.push(步进索引);
}
});
如果(newMedias.length>0){
return forkJoin(newMedias).pipe(mergeMap)(medias)=>{
medias.forEach((media,i)=>{
payload.formData.steps[newMediaInStepIndex[i]].media[0].id=media.id;
});
返回此.createRecipe(有效载荷);
}));
}否则{
返回此.createRecipe(有效载荷);
}
}
我通过
管道中的
mergeMap
更改
subscribe
。我在返回我的
forkJoin
时返回一个
observed
,并在
save(p)
结束时返回该值


我添加了以下内容:
constpayload=JSON.parse(JSON.stringify(p))
因为p来自
@ngrx

类似的问题
https://stackoverflow.com/q/48879798/1876572
@Eldho,在本例中,
save(isNew)
不会返回。这就是我的问题。您的代码最终将为每个可观察对象调用createRecipe。OP希望在收到所有有效负载后运行createRecipe。ForkJoin仅在解决所有请求后获取订阅。尝试为您查找示例。希望这个答案能说明这一点,也请仔细阅读答案
forkJoin等待所有可观察到的内容完成。
如果
newMedias
为空
this.createRecipe(有效负载)从不调用这是因为从未调用订阅本身。只有当newMedias不为空时,才应该执行forkJoin。否则直接打电话给createRecipe谢谢,您的解决方案很好。我刚刚遇到了媒体id设置器的最后一个问题。错误类型错误:无法添加属性id,对象不可扩展。您需要将有效负载对象克隆到新对象中并在其中分配它。在内部,对有效负载对象调用了一个preventExtensions。阅读这里,我尝试
const p=Object.assign({},payload)但不起作用好的解决方案!在我的例子中,“mergeMap”方法不起作用,“map”起了作用。
forkJoin(newMedias).subscribe(medias => {
    medias.forEach((media, i) => {
      console.log('Media created with id: ' + media.id + ' in step ' + newMediaInStepIndex[i]);
      payload.formData.steps[newMediaInStepIndex[i]].media[0].id  = media.id;
    });
  },
err => {},
() => {
    this.createRecipe(payload);
});
private save(p): Observable<Action> {

    const payload = JSON.parse(JSON.stringify(p));

    const newMedias: Observable<Media>[] = [];
    const newMediaInStepIndex: number[] = [];

    (payload.formData.steps).forEach((step: Step, stepIndex: number) => {
        const media: Observable<Media> = this.createOneMedia(step);
        if (media !== undefined) {
          newMedias.push(media);
          newMediaInStepIndex.push(stepIndex);
        }
    });

    if (newMedias.length > 0) {
        return forkJoin(newMedias).pipe(mergeMap( (medias) => {
          medias.forEach((media, i) => {
            payload.formData.steps[newMediaInStepIndex[i]].media[0].id = media.id;
          });
          return this.createRecipe(payload);
        }));
    } else {
        return this.createRecipe(payload);
    }

}