【问题标题】:Angular with RxJs: Ensuring all observables are completed beforeAngular 与 RxJs:确保所有 observables 在之前完成
【发布时间】:2020-11-20 21:52:05
【问题描述】:

我有以下使用 RxJs 的 Angular 代码:

private loadData(id) {
    
        const inputData = .....

        this.backendservice.getData(inputData).pipe(take(1)).subscribe(data => {
            // do stuff
        });
        
}

目前的代码只处理一个 id。 现在我想让它适用于多个 id,并有一个可能的代码结构,如:

private loadData(ids) {

        const Map myMap = new Map();
        for(let id of ids) {
           const inputData = .....
           this.backendservice.getData(inputData).pipe(take(1)).subscribe(data => {
               myMap.set(inputData, data)
               // do stuff
           });
        }
        // do more stuff with myMap
}

我想在执行“做更多事情”部分之前处理所有 ID。我在订阅代码中更新了一个地图并在之后使用它。在 Angular 中使用 RxJs 实现这一目标的最佳方法是什么?

【问题讨论】:

  • 使用 forkJoin()...

标签: angular rxjs


【解决方案1】:

使用forkJoin,如下所示:

private loadData(ids) {
        let observables=[];
        for(let id of ids) {
           const inputData = .....
           observables.push(
               this.backendservice.getData(inputData).pipe(take(1)).subscribe(data => {
                    // do stuff
                });
           )
        }
        forkJoin(observables).subscribe(res=>{
            // do more stuff
        })       
}

【讨论】:

  • 在“做事”中,我正在更新一个以“inputData”为键的地图对象,然后我在“做更多事”中使用该地图。看来您建议的代码结构将不起作用。
  • 只要在 loadData 范围内声明就可以了。当你做更多的事情时,你在做的事情中所做的任何操作都将可用
  • 在此处回答 stackoverflow.com/questions/53088099/… 订阅中没有“res”。它有 () 代替。会有所不同吗?
  • 在那个问题中,observables 的输出不是必需的(只是知道它们已经全部完成),所以没有必要。 res 将是您的 observables 输出的数组。如果您需要该信息,您可以使用它。由于问题没有具体说明,我将其包括在内。
  • 如果我们在 push 中调用 subscribe,那么这是否意味着我们实际上没有一个 observable。
【解决方案2】:

听起来您想要forkJoin 一个流数组,然后获取结果并将其转换为Map

我添加了一些 console.log() 语句,它们可以充当调试点,帮助您更好地获得/理解您的解决方案。它可以采取的一般形状可能如下所示:

private loadData(ids): void {

  forkJoin(
    ids.map(id => {
      const inputData = ...;
      return this.backendservice.getData(inputData).pipe(
        take(1),
        map(data => ({id, inputData, data})),
        tap(result => console.log(`Service call ${result.id} complete`))
      );
    })
  ).pipe(
    tap(_ => console.log("All Service calls complete and output as an array")),
    map(resultArray => {
      const myMap = new Map();
      for(const result of resultArray){
        myMap.set(result.inputData, result.data);
        console.log(`Results from call ${result.id} added to Map`);
      }
      return myMap;
    }),
    tap(_ => console.log("Call resuls transformed into a Map data structure"))
  ).subscribe(myMap => {
    // Do more stuff with myMap
  });

}

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多