简体   繁体   English

重置 RxJS concatMap 而不完成外部 Subject

[英]Reset RxJS concatMap without completing the outter Subject

I'm using a concatMap to handle multiple requests to an API, where I want each request batch to be completed before the next batch is processed.我正在使用concatMap处理对 API 的多个请求,我希望在处理下一个批次之前完成每个请求批次。 The concatMap works as expected when triggering the flow with callSubject.next(requestData) concatMap在使用callSubject.next(requestData)触发流程时按预期工作

The problem: for certain types of requestData I want to cancel any in-flight http calls, and reset the concatMap .问题:对于某些类型的requestData我想取消任何飞行中的 http 调用,并重置concatMap Cancelling the httpClient calls that are occurring within the getAll function is handy enough (I have a takeUntil that does that - not shown), but the concatMap may still have a number of queued up requests that will then be processed.取消getAll function 中发生的httpClient调用非常方便(我有一个takeUntil可以做到这一点 - 未显示),但concatMap可能仍然有许多排队的请求,然后将被处理。

Is there a way to reset the concatMap without completing the callSubject Subject?有没有办法在不完成callSubject主题的情况下重置concatMap

Note: if I trigger unsubscribeCallSubject$.next() this clears the concatmap, but also completes the callSubject, which means it can no longer be used with callSubject.next(reqData)注意:如果我触发unsubscribeCallSubject$.next()这将清除 concatmap,但也会完成 callSubject,这意味着它不能再与callSubject.next(reqData)一起使用

// callSubject is a Subject which can be triggered multiple times
callSubject
  .pipe(
    concatMap((req) => {
      // getAll makes multiple httpClient calls in sequence
      return getAll(req).pipe(
        catchError((err) => {
          // prevent callSubject completing on http error
          return of(err);
        })
      );
    }),
    takeUntil(unsubscribeCallSubject$)
  )
  .subscribe(
    (v) => log("callSubject: next handler", v),
    (e) => log("callSubject: error", e),
    () => log("callSubject: complete")
  );

If I understand the problem right, you could try an approach which uses switchMap any time unsubscribeCallSubject$ emits.如果我理解正确的问题,您可以尝试在unsubscribeCallSubject$发出时随时使用switchMap的方法。

The code would look something like this代码看起来像这样

unsubscribeCallSubject$.pipe(
  // use startWith to start the stream with something
  startWith('anything'),
  // switchMap any time unsubscribeCallSubject$ emits, which will unsubscribe 
  // any Observable within the following concatMap
  switchMap(() => callSubject$),
  // concatMap as in your example
  concatMap((req) => {
      // getAll makes multiple httpClient calls in sequence
      return getAll(req).pipe(
        catchError((err) => {
          // prevent callSubject completing on http error
          return of(err);
        })
      );
    }),
)
.subscribe(
    (v) => log("callSubject: next handler", v),
    (e) => log("callSubject: error", e),
    () => log("callSubject: complete")
);

To be honest I have not tested this approach and so I am not sure whether it solves your problem, but if I have understood your problem right, this could work.老实说,我没有测试过这种方法,所以我不确定它是否能解决你的问题,但如果我正确理解了你的问题,这可能会奏效。

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

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