总结:我正在使用Rxjs和一个新手。我希望实现这样一个具有可观察性的场景,但到目前为止还没有运气。
有一个函数loadDetailsFromServer(itemIds),它调用服务器api并传递一些项目ID。这个函数偶尔称为。为了优化服务器调用,这是我想要做的: 在第一次函数调用到达时,触发超时。如果在超时之前任何新函数调用到达,则重置timout以再次启动。当超时启动时,进行服务器调用,并且参数计数重置为零。
这是一张大理石图:
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.
提示:这类似于搜索框样本并从服务器获取结果,除了临时值是感兴趣的,并且不会被忽略/跳过。
答案 0 :(得分:1)
例如,如果你有这样的源Observable:
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));
然后,您可以使用scan
缓冲其值。要使用.merge(bufferNotifier.mapTo(null))
重置缓冲区,请执行此操作。然后使用switchMap()
我总是等待1000毫秒才能发出forkJoin()
。如果它没有"覆盖"另一个Observable是因为新的缓冲区到了:
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 ]
答案 1 :(得分:0)
如果你对马丁的答案有类似的source
观察,那么这样的事情可能有效:
source
.buffer(source.debounceTime(250))
.subscribe(console.log);
buffer
收集所有发出的值,直到给定的observable发出。在这种情况下,它会等到debounceTime
发出。 CodePen:https://codepen.io/anon/pen/PKBaZm?editors=1010