【问题标题】:RxJS array of HTTP observables: fire next only after previous completesHTTP observables 的 RxJS 数组:仅在上一个完成后触发下一个
【发布时间】:2021-01-24 22:43:20
【问题描述】:

我有一个可观察的数组(HTTP POST 请求),我需要在特定事件之后将它们发送到 API。以下是该方法的简化示例,我使用concat,因此我可以利用成功、错误和完成回调。

// build up an array of stored POST requests to fire off later
// array is indeterminate length, could be 1 request could be 1,000
let requests = [ req1, req2, req3, req4 ];

concat(...requests).subscribe(
  success => ... handle success ...
  error => ... handle error ...
  () => ... handle completion ...
);

问题在于 concat 基本上是一次发送所有请求,这增加了使用请求的 API 中并发问题的可能性。如果我能够逐个而不是一次全部触发请求,则应该解决此问题。我已经确定 forEach 循环不是一个选项。

是否有一种 RxJS 方法使得 req2 仅在 req1 完成后发出,req3 仅在 req2 完成后发出等等?我一直在查看 RxJS 文档,但还没有找到适合这种情况的任何内容。

【问题讨论】:

  • 对使用闭包的依赖项使用异步等待。将 observable 转换为 Promise 以完成它。
  • "问题是 concat 基本上一次发送所有请求" -> concat 应该按顺序触发 observables,只有在第一个请求完成后才继续执行后续请求。 Example
  • 带有concat 的代码应该可以按预期工作。如果没有,请提供重现问题的堆栈闪电战。

标签: angular rxjs rxjs6 rxjs-observables


【解决方案1】:

您可以使用 RxJS from 函数和高阶映射运算符 concatMap

试试下面的

from(requests).pipe(
  concatMap(req => req)
).subscribe(
  success => ... handle success ...
  error => ... handle error ...
  () => ... handle completion ...
);

如果没有concatMap 运算符,数组的请求元素将作为可观察对象逐字发出,而不是被触发。您可以在我的其他答案 here 中找到 b/n 高阶映射运算符的差异。

【讨论】:

  • @RafiHenig:concat 应该按顺序发送请求。但是您说“(它)基本上一次发送所有请求”。在没有看到请求的性质的情况下,我的答案是我能想出的下一个替代方案。它确保排放是连续的。您可以在 Stackblitz 中看到差异。
猜你喜欢
  • 2020-09-27
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 2020-11-23
  • 1970-01-01
相关资源
最近更新 更多