由于pausable
运算符未在RxJS v5中实现,是否有更好的方法来创建可暂停的间隔?下面的代码可以工作,但是通过跟踪最后一个发射值作为偏移来实现。似乎应该有更好的方式...
const source = Rx.Observable.interval(100).share()
const offset = new Rx.BehaviorSubject(0)
let subscription;
let currentValue;
function start() {
subscription = source
.subscribe(i => {
currentValue = i + offset.value
})
}
function pause() {
source.take(1).subscribe(i => offset.next(i + offset.value))
subscription.unsubscribe()
}
答案 0 :(得分:1)
share()
运算符为an alias for .publish().refCount()
。 refCount()
意味着当没有其他订阅者存在时,observable将自我清理。因为您从源代码取消订阅,它将自行清理,然后在subscribe
d再次重新启动时重新启动。请将publish()
与connect()
一起使用。这是代码:
const source = Observable.interval(100).publish();
source.connect();
// Start with false, change to true after 200ms, then false again
// after another 200ms
const pauser = Observable.timer(200)
.mapTo(true)
.concat(Observable.timer(200).mapTo(false))
.startWith(false);
const pausable = pauser
.switchMap(paused => (paused ? Observable.never() : source))
.take(10);
pausable.subscribe(x => console.log(x));
有关正在运行的示例,请参阅此jsbin:http://jsbin.com/jomusiy/3/edit?js,console。
答案 1 :(得分:0)
没有通用的方法来做到这一点。这取决于您暂停的具体含义以及您暂停的内容。 (你想停止发射,然后重新开始,你是否缓冲和消耗,或者你是否真的需要向上游添加延迟,但是否能及时保留上游值的分布?)
当上游特别是一个计时器时,我有办法以有效的方式执行此操作,就像在您的示例中一样。这是我自己的问题的答案。
RxJS (5.0rc4): Pause and resume an interval timer
这个有很大的优势,可以及时保留源的价值分布,但只是增加了延迟。
对于更一般的情况:
对于冷可观测量:switch
在never
和上游之间。暂停时,取消订阅上游。 skip
您已经看到的,然后switch
到skip
ed流。在取消暂停时,您必须保留已发出的值的数量,以便下次有人取消暂停时可以skip
。你只需要记住你之前见过的人数。但是,每次取消都会导致冷可观察性从一开始就重放。在一般情况下,这可能非常效率低下。代码看起来像这样。 pauser
这里是一个主题,你可以设置为true或false来暂停上游。
function pausableCold(pauser, upstream) {
var seen = 0;
return pauser.switch(paused => {
if (paused) {
return Observable.never();
}
else {
return upstream.skip(seen).do(() => seen++);
}
});
}
对于热或冷可观测量,您可以使用缓冲。暂停时buffer
暂停,然后在取消暂停时排空并连接到热的上游。 (这保留了所有的值,但它并没有及时保留它们的分布。另外,如果它可能很冷,你应该用publish
加热上游。)
最有效的方式并不是Rx的一部分。你真正想要的是告诉来源停止发光,然后重新开始。您这样做的方式非常特定于源是什么以及源如何生成值。