【问题标题】:RxJS - Queueing ajax requests from separate inputsRxJS - 对来自不同输入的 ajax 请求进行排队
【发布时间】:2018-03-26 08:15:37
【问题描述】:

我有多个输入的列表(动态生成 - 未知数)。

  • 我希望每个人在每次击键时触发一个 ajax 请求

  • 我想让这些 ajax 请求排队,所以只发送一个到 服务器一次,只有在得到前一个服务器的响应后才会发送下一个。

  • 如果从队列中已有请求的输入触发新请求,我希望取消与同一输入关联的旧请求。

  • 如果新请求是从队列中没有的输入触发的,我希望将新请求添加到队列末尾而不取消任何内容。

有人告诉我 RxJS 让这些复杂的异步操作变得简单,但我似乎无法理解所有的 RxJS 操作符。

我在下面排队处理单个输入,但我真的不明白为什么延迟是必要的,或者如何在保持我认为我想要的单个输入本身的类似 switchMap 的行为的同时对单独输入的请求进行排队。

Rx.Observable.fromEvent(
    $("#input"),
    'keyup'
)
.map((event) => {
    return $("#input").val();
});
.concatMap((inputVal) => {
    return Rx.Observable.defer(() => Rx.Observable.fromPromise(
        fetch(myURL + inputVal)
    ))
    .catch(() => Rx.Observable.empty());
})
.subscribe();

【问题讨论】:

    标签: rxjs rxjs5


    【解决方案1】:

    首先,您必须创建某种函数来管理每个输入。大致如下

    requestAtKeyStroke(inputId: string) {
       return Rx.Observable.fromEvent(
               $(inputId),
               'keyup'
             )
             .map((event) => {
                return $("#input").val();
             })
            .filter(value => value.length > 0)
            .switchMap((inputVal) => Rx.Observable.fromPromise(fetch(myURL + inputVal)))
    }
    

    这样的功能处理您的第三个必要条件,即在新请求到达时取消仍在进行中的请求。这里的关键是switchMap 运算符。

    那么你可以做的就是将你的输入对应的所有 Observable 合并到一个 Observable 中。一种方法可能是以下

    Observable.from(['input1, 'input2']).map(input => requestAtKeyStroke(input)).mergeAll()
    

    这并不能满足您的所有要求,因为您仍然可能同时执行多个来自不同输入的请求。我不确定是否可以同时满足您的所有要求。

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 2018-10-13
      • 2017-07-24
      相关资源
      最近更新 更多