我如何使用RxJs来阻止对AJAX调用的任何请求,直到前一个请求解决

How can I use RxJs to hold off any requests for an AJAX call until the previous one resolves

本文关键字:请求 解决 一个 任何 RxJs 何使用 调用 AJAX      更新时间:2023-09-26

我有一个可观察对象,它表示由某个外部组件触发的操作。为了这个问题的目的,我们叫它createBananaAction。我有一个bananaService和一个方法create,它执行AJAX请求并返回创建的香蕉作为Promise

因此,每当有数据从createBananaAction到达时,我们想要调用bananaService.create()

代码如下:(使用RxJs)

this.createdBananas = createBananaAction.flatMap(() => bananaService.create());

现在,挑战是"节流"createBananaAction,以便它只能在收到前一个香蕉后请求另一个香蕉。简单地说:永远不可能有两个同时调用bananaService.create()。注意,我不想在时间上节流,而是在bananaService工作时忽略所有对新香蕉的传入请求。

我做了一些研究,找到了似乎合适的pausable运算符。

我的代码现在看起来像这样:
const pausableCreateBananaAction = createBananaAction.pausable();
this.createdBananas = pausableCreateBananaAction
    .do(() => pausableCreateBananaAction.pause())
    .flatMap(() => bananaService.create())
    .do(() => pausableCreateBananaAction.resume());

这似乎工作,但我不喜欢这样的事实,我需要这些do语句手动触发pauseresume语句。

我发现你可以将一个可观察对象传递到pausable,然后在适当的时候产生falsetrue,但这也需要我在主题中手动推送值。像这样:

const letItGoThrough = new Rx.Subject();
this.createdBananas = createBananaAction
    .pausable(letItGoThrough.startWith(true))
    .do(() => letItGoThrough.onNext(false))
    .flatMap(() => bananaService.create())
    .do(() => letItGoThrough.onNext(true));

现在我有一个Rx。主题(主题就像rxj的训练轮,直到你对rxj有足够的经验,你不再需要它们。)和两次调用do

是否有一种完全"被动"的方式来做我想做的事情?还是我被这个看起来和感觉对我的口味来说有点太重要的结构所困住了?

提前谢谢你。

使用flatMapFirst代替flatMap:

this.createdBananas = createBananaAction.flatMapFirst(() => bananaService.create());

上面假设你的bananaService.create()返回一个冷的可观察对象。如果它返回一个热可观察对象或Promise,那么我们需要用Observable.defer包装调用,将其转换为一个冷可观察对象,以便flatMapFirst可以正确控制其触发:

this.createdBananas = createBananaAction
    .flatMapFirst(() => Rx.Observable.defer(() => bananaService.create()));