如何使用angular 6和RxJs 6从forkJoin的订阅返回值?
所以我需要在订阅结束后返回end。我想我们必须把这个函数减半如何使用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:
重要提示:返回保存(有效负载)需要一个函数来返回从
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);
}
}