Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
RxJs Angular 7 HttpClient使用forkJoin多次发布删除第二次订阅?_Angular_Loops_Rxjs_Observable - Fatal编程技术网

RxJs Angular 7 HttpClient使用forkJoin多次发布删除第二次订阅?

RxJs Angular 7 HttpClient使用forkJoin多次发布删除第二次订阅?,angular,loops,rxjs,observable,Angular,Loops,Rxjs,Observable,我正在使用链接的子任务对象创建工作项对象。我的函数(createWorkItemAndChildren)接受两个参数:workItem和任务对象数组。我希望我的函数返回创建的所有ID(工作项和任务)的数组 我必须先从一个http POST调用(workItemService.createWorkItem)返回父ID,然后才能创建在同一服务上使用另一个http POST方法的子任务 我现在让forkJoin在createChildWorkItems中一次返回所有子ID 我如何重构它,以便只有一个订

我正在使用链接的子任务对象创建工作项对象。我的函数(createWorkItemAndChildren)接受两个参数:workItem和任务对象数组。我希望我的函数返回创建的所有ID(工作项和任务)的数组

我必须先从一个http POST调用(workItemService.createWorkItem)返回父ID,然后才能创建在同一服务上使用另一个http POST方法的子任务

我现在让forkJoin在createChildWorkItems中一次返回所有子ID

我如何重构它,以便只有一个订阅,并返回带有父ID和子ID的数组

createChildWorkItems(parentId,tasks:Task[]):可观察{
返回叉连接(
tasks.map(task=>this.workItemService.createChildWorkItem(parentId,task))
).pipe(zip());
}
createWorkItemAndChildren(workItem,childTasksToSave:Task[]){
var resultArray=[];
此.workItemService.createWorkItem(workItem).subscribe(workItemId=>{
var parentId=workItemId;
resultArray.push(parentId);
if(parentId!==null){
this.createChildWorkItems(parentId,childTasksToSave).subscribe((结果:number)=>{
结果ray.push(结果);
this.tfsIdsCreated=resultArray;
});
}
});
}

在您的情况下,孩子不适合fork-join。但这里应该使用Async/await。fork join以异步方式发送请求,但Async/wait将在收到响应时等待每个请求的响应,并将该响应附加到父simple, 在异步/等待中,请求将像循环一样依次进行。完成所有请求后,返回该对象 这是asyn/WAIT的链接


}

如果您想并行执行子任务,这是您的选择

下面是一个粗略的例子:

createParent().pipe(
//从父流切换到forkJoin(…子流)
合并映射(父项=>
//等待创建所有子项
forkJoin(children.map(child=>createChild(parent,child))).pipe(
//将childResults与parent合并
映射(childResults=>{
//对父级和所有子级执行操作
parent.childResults=childResults;
//切换回父级
返回父母;
})
)
)
)
.订阅(父项=>{
// ...
})
注意我们如何只订阅一次Observable-这是一个好的实践

这里不需要
async wait


希望这有助于

创建一个观察数组,并将引用传递到forkjoin中

let observableBatch= [];

for (let child of childTasksToSave){
   observableBatch.push(this.workItemService.createChildWorkItem(parentId, child));
}

Observable.forkJoin(observableBatch).subscribe...;
参考:

以下是我最后做的事情,这就是我接受kos答案的原因: 我的TfsIsCreated数组正在订阅结果,该结果提供ID列表

createParentAndKids(workItem, childTasksToSave){
    this.workItemService.createWorkItem(workItem).pipe(
      mergeMap(parentId => {
        if (parentId === null){
          return of([parentId]);
        }

        const childTaskObservables$ = childTasksToSave.map(
          child => this.workItemService.createChildWorkItem(parentId, child)
        );

        return forkJoin(childTaskObservables$).pipe(
          map(ids => [parentId, ...ids])
        );

      })
    ).subscribe(x => this.tfsIdsCreated.push(x));
  }

async await的语法是如何更改的?将async关键字添加到createWorkItemAndChildTasks尝试以下操作。。异步createWorkItemAndChildTasks(workitem,childTasksToSave:Task[]){//for(让childTasksToSave的子项){const Task=fetchChild(parentId,child);if(Task!==null){console.log('createWorkItem接收的子任务ID:'+Task);this.tfsIdsCreated.push(Task);}}async fetchChild(parentId,child){const response=wait this.workItemService.createChildWorkItem(parentId,child).toPromise();返回响应;我感谢您的建议,但我在理解如何使我的代码适应这一点时仍有一些问题。在您的createParent()中示例代码,这是返回一个可观察的还是一个数字?@JenniferS,
createParent()
应该返回Observable,类似于您的
this.workItemService.createWorkItem
。在这里,我编译了一个小示例,更接近您的代码:感谢您的额外解释。但是rxObserver在做什么?@Jennifer它是图表API的一部分,用于呈现那些大理石图。它实现了接口,因此您可以替代如果希望将其输出到控制台,请使用
x=>console.log(x)
。@JenniferS,很高兴听到这个消息:)GL
createParentAndKids(workItem, childTasksToSave){
    this.workItemService.createWorkItem(workItem).pipe(
      mergeMap(parentId => {
        if (parentId === null){
          return of([parentId]);
        }

        const childTaskObservables$ = childTasksToSave.map(
          child => this.workItemService.createChildWorkItem(parentId, child)
        );

        return forkJoin(childTaskObservables$).pipe(
          map(ids => [parentId, ...ids])
        );

      })
    ).subscribe(x => this.tfsIdsCreated.push(x));
  }