从Observable中取消传入的数据

时间:2017-06-26 10:15:44

标签: angular rxjs observable unsubscribe

我有Angular输入,每当它的值发生变化时我会要求服务获取有关输入值的一些数据。我只关心最后输入的输入,所以当用户输入'1',然后删除它并输入'2'时我不关心有关先前值的数据。我写了这样的东西(我保留prevNr中先前请求的值):

let stream,
  nr = document.querySelector('input').value;

if (status === `${nr} in progress`) {
  stream.unsubscribe();
  console.log(`subscription of ${prevNr} cancelled`)
}

status = 'in progress';
prevNr = nr;

console.log(`started subscription of ${nr}`)
stream = someService.someMethod.subscribe(() => {
  const clonedNr = nr;
  setTimeout(() => {
    status = 'done';
    console.log(`received response for ${clonedNr}`)
  }, 12000);
})

我在控制台中得到的是

1 in progress

subscription of 1 cancelled
2 in progress

subscription of 2 cancelled
3 in progress

subscription of 3 cancelled
4 in progress

received response for 1
received response for 2
received response for 3
received response for 4

现在我通过setTimeout()模拟响应,但是我可以想象在输入3的数据之前我接收输入4的数据的情况,结果这个数据将被分配给错误的输入。 如何省略Observable中的先前请求?这可能吗?

1 个答案:

答案 0 :(得分:0)

一些注意事项:

您可能希望将 debounce 添加到nr流。这样,如果用户快速成功地键入多个号码,您就不会发送每个号码的请求。 debounceTime()允许您在输入值后等待设定的金额毫秒,如果在该时间内没有输入新值,则传递该值。如果在设定时间内输入新值,则时间将被重置;冲洗并重复。

您不应该在subscribe()中执行异步工作,而是"某种"打破Rx。所有异步工作都应该在subscribe()之前在另一个运算符内完成;通常是*Map()运营商之一。

我假设someMethod()返回一个可观察对象(或者您可以将其转换为一个),在这种情况下,您将需要switchMap()运算符。你返回一个可观察的内部switchMap(),它只会订阅最新的observable。它也将取消订阅之前的观察结果。

let stream,
nr = document.querySelector('input').value
    .debounceTime(500); // This will wait 500 ms before passing on a value
                        // If a new value arrives before 500ms has passed, it resets the time

stream = nr
    .switchMap(num => someService.someMethod(num))
    .subscribe(clonedNr => console.log(`received response for ${clonedNr}`));