RxJS - 从单独的输入

时间:2018-03-26 08:15:37

标签: rxjs rxjs5

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

  • 我希望每个人都能在每次击键时触发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();

1 个答案:

答案 0 :(得分:0)

首先,您必须创建一些管理每个输入的函数。以下几行

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()

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