Function rxjs缓冲区,直到新arg到达时超时重置
小结:我正在使用Rxjs和一个新手。我想实现这样一个场景,可以观察到,但到目前为止还没有运气 有一个函数loadDetailsFromServer(ItemId),它调用服务器api并传递一些ItemId。此函数偶尔调用。要优化服务器调用,我想做以下几点: 当第一个函数调用到达时,将触发超时。如果在超时之前任何新函数调用到达,timout将重置为重新启动。当超时开始时,进行服务器调用,参数计数重置为零 这是一张大理石般的图表:Function rxjs缓冲区,直到新arg到达时超时重置,function,rxjs,accumulate,debounce,Function,Rxjs,Accumulate,Debounce,小结:我正在使用Rxjs和一个新手。我想实现这样一个场景,可以观察到,但到目前为止还没有运气 有一个函数loadDetailsFromServer(ItemId),它调用服务器api并传递一些ItemId。此函数偶尔调用。要优化服务器调用,我想做以下几点: 当第一个函数调用到达时,将触发超时。如果在超时之前任何新函数调用到达,timout将重置为重新启动。当超时开始时,进行服务器调用,参数计数重置为零 这是一张大理石般的图表: Timer is 4 clicks. INPUTS IN TIME
Timer is 4 clicks.
INPUTS IN TIME 1-2---3-4-----5--------6-7--------
loadDetailsFromServer [1,2,3,4] - [5] -[6,7]
function called with [1,2,3,4] because no more calls after 4 clicks.
提示:这类似于搜索框示例并从服务器获取结果,不同之处在于中间值很重要,不会被忽略/跳过。例如,如果您有如下可观察的源:
const Rx = require('rxjs/Rx');
const Observable = Rx.Observable;
const TIMEOUT = 1000;
const source = Observable.range(1, 20)
.concatMap(v => Observable.of(v).delay(Math.random() * 2000));
然后可以使用扫描缓冲其值。要重置缓冲区,我正在使用.merge(bufferNotifier.mapTo(null))
。然后使用switchMap()
我总是等待1000毫秒,等待forkJoin()
发出。如果没有,则会被另一个可观察对象“覆盖”,因为新缓冲区已到达:
const bufferNotifier = new Subject();
const chain = source
.do(undefined, undefined, () => bufferNotifier.complete()) // properly complete the chain
.merge(bufferNotifier.mapTo(null)) // reset buffer Subject
.scan((acc, val) => {
if (val === null) {
return [];
}
acc.push(val);
return acc;
}, [])
.filter(arr => arr.length > 0)
.switchMap(buffer => { // wait 1s until emitting the buffer further
return Observable.forkJoin(
Observable.of(buffer),
Observable.timer(1000).take(1),
arr => arr
);
})
.do(() => bufferNotifier.next()) // trigger reset the buffer
.subscribe(console.log);
这将输出例如:
[ 1 ]
[ 2 ]
[ 3, 4 ]
[ 5 ]
[ 6, 7 ]
[ 8, 9, 10, 11, 12 ]
[ 13 ]
[ 14, 15 ]
[ 16 ]
[ 17 ]
[ 18 ]
[ 19, 20 ]
如果你有一个类似的源代码
可以观察到martin的答案,类似的东西可能会起作用:
source
.buffer(source.debounceTime(250))
.subscribe(console.log);
buffer
收集所有发射值,直到给定的可观测发射。在这种情况下,它将等待debounceTime
发出。代码笔: