简体   繁体   English

RxJS:在最后一个 switchMap 中带有轮询的调用链

[英]RxJS: chain of calls with polling in the last switchMap

I have a very complicated example of chained RxJS calls with a lot of switchMap and etc. Everything is clear for me until I faced one requirement: I need to poll last request every 5 sec until response object contains a value.我有一个非常复杂的示例,它使用大量switchMap等链接RxJS调用等。在我遇到一个要求之前,一切对我来说都很清楚:我需要每 5 秒轮询最后一个请求,直到响应 object 包含一个值。 I stuck a bit... I know how to make it if I have only polling or if I have only plain switchMap .我有点卡住了......如果我只有 polling 或者我只有普通switchMap ,我知道如何做到这一点。

this.articleService.create(data).pipe(
  switchMap((article: ArticleCreateModel) => this.articleService.getArticle(article.id)),
  switchMap((article: ArticleCreateModel) =>
    this.articleService.update({
      ...article,
      timestamp: this.someFakeService.getData(),
    }),
  ),
  // somehow I need to poll next createAsyncCommentsSection every 5 sec until response object key is let's say 'true'
  switchMap((article: ArticleCreateModel) => this.articleService.createAsyncCommentsSection(article.id)),
);

How can I poll last switchMap every 5 sec until response object key is let's say 'true'.如何每 5 秒轮询最后一个 switchMap,直到响应 object 键让我们说“真”。 And retry it only 5 times?并且只重试5次?

I tried so, but it looks like it doesn't work:我试过了,但看起来它不起作用:

  switchMap((article: ArticleCreateModel) =>
    this.articleService.createAsyncCommentsSection(article.id).pipe(
      delay(5000),
      filter((article: ArticleCreateModel) => !!article.hasSyncedWithOtherAPI),
      take(5),
    ),
  ),

You can create a single observable that polls and emits when response.isComplete like this:您可以创建一个可在response.isComplete时轮询和发出的单个 observable,如下所示:

timer(0, 5000).pipe(
    take(5),
    switchMap(() => this.articleService.createAsyncCommentsSection(articleId)),
    filter(response => response.isComplete),
    first()
);

timer() will emit immediately, then every 5 seconds; timer()将立即发出,然后每 5 秒发出一次; a maximum of 5 times thanks to take(5) .感谢take(5)最多 5 次。

filter prevents emissions until your condition is met. filter防止排放,直到满足您的条件。

first will take only 1 emission, but will throw an error if no emission is received before the stream is completed. first只需要 1 个发射,但如果在 stream 完成之前没有收到发射,则会抛出错误。

So altogether, could look like this:总而言之,可能看起来像这样:

this.articleService.create(data).pipe(
  switchMap((article: ArticleCreateModel) => this.articleService.getArticle(article.id)),
  switchMap((article: ArticleCreateModel) =>
    this.articleService.update({
      ...article,
      timestamp: this.someFakeService.getData(),
    }),
  ),
  switchMap((article: ArticleCreateModel) => timer(0, 5000).pipe(
    take(5),
    switchMap(() => this.articleService.createAsyncCommentsSection(article.id)),
    filter(response => response.isComplete),
    first()
  )
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM