【问题标题】:RxJS forkJoin of chained requests?RxJS forkJoin 链接请求?
【发布时间】:2020-12-14 23:25:11
【问题描述】:

我有

const jobsToRun = this.config.data.tests.map(test => test.location);
const jobsSubmits: any[] = jobsToRun
    .map(job => this.jobsService.submitTestJob(job).pipe(first())); // HERE

const finito = await forkJoin(jobsSubmits).toPromise();

所以我并行提交测试并等待所有提交完成。我想以某种方式改进这一点,即提交测试并使用来自响应(提交)的数据,更新数据库(另一个调用)。

我如何最好地实现这个 forkJoin(submitTest -> 在数据库中记录提交)?我想我只是不知道哪个 RxJS 运算符是理想的。

finito解决之后再做是不可行的,我需要在个人测试提交后尽快将记录入库。

【问题讨论】:

    标签: rxjs


    【解决方案1】:

    将第一次调用的结果转换为第二次调用的结果应该很简单。

    类似这样的:

    const jobsSubmits = this.config.data.tests
      .map(test => test.location)
      .map(job => this.jobsService.submitTestJob(job).pipe(
        first(),
        switchMap(submitted => this.jobsService.makeRecordABout(submitted))
      ));
    
    const finito = await forkJoin(jobsSubmits).toPromise();
    

    【讨论】:

    • switchMap 与 concatMap 有什么好处(如果有的话)?我已经阅读了有关运营商的信息,但在我的特定情况下没有看到太大的区别,因为我的提交发出了 2 个值(相同,由于设计缺陷不在我的管辖范围内,所以我利用 first() 始终拥有1个值)我是否等待都没关系
    • 是的,first() 采用第一个值并完成流。在这种情况下,mergeMapconcatMapswitchMap 都会产生相同的输出。 switchMap 是这 3 个中唯一一个一次不管理多个订阅的人,因此它倾向于在这种情况下使用,因为它“感觉”是最合适的。实际上,这并不重要。
    【解决方案2】:

    我假设submitTestJob 是一个返回Observable 的远程http 调用。 如果这是真的,我会做这样的事情

    const jobsSubmits = jobsToRun
        .map(job => this.jobsService.submitTestJob(job).pipe(
              // if submitTestJob is an http call, then first should not be necessary
              first(),
              // addRecord is a function which returns an Observable which emits when
              // the record is added
              concatMap(submission => addRecord(submission))
           )
        );
    

    您可以在this article 中阅读更多关于典型 rxjs 模式的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      • 2021-11-24
      • 2020-04-26
      • 2018-10-12
      相关资源
      最近更新 更多