2017-06-26 35 views
0

我有Angular输入,每当它的值发生变化时我要求服务获取有关输入值的一些数据。我只关心最后输入的输入,所以当用户输入'1',但是然后擦除它并输入'2'时,我不关心关于先前值的数据。我写了这样的事情(我一直在prevNr先前请求的值):取消来自Observable的传入数据

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中省略先前的请求?那可能吗?

+0

中的第三个回调函数订阅为[完成](http://reactivex.io/rxjs/class/es6/Subscriber.js~Subscriber.html) – Dhyey

回答

0

的几个注意事项:

你可能想一个去抖添加到nr流。这样,如果用户以快速成功键入多个号码,则不会为每个号码发送请求。 debounceTime()允许您在输入一个值后等待一个毫秒的设定值,如果在那段时间内没有输入新的值,它会被传递。如果在设定时间内输入新值,时间将被重置;冲洗并重复。

您不应该在subscribe()中执行异步工作,它会“破坏”Rx。所有异步工作应在subscribe()之前在另一个运营商内完成;经常是一个*Map()运营商。


我假设someMethod()返回一个可观察到的(或者你也许可以将其转换为一个),在这种情况下,你会希望switchMap()操作。您返回switchMap()中的可观察值,它只会订阅最近的可观察值。它也将退订先前的观察。

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}`));