我们说我们有一个 Observable :
var observable = Rx.Observable
.fromEvent(document.getElementById('emitter'), 'click');
如何才能完成(所有订阅的观察员会触发 onComplete 事件)?
答案 0 :(得分:23)
在目前的形式中,你不能。您的observable源自一个未完成的源,因此它本身无法完成。您可以做的是使用完成条件扩展此源。这可以像:
var end$ = new Rx.Subject();
var observable = Rx.Observable
.fromEvent(document.getElementById('emitter'), 'click')
.takeUntil(end$);
如果要结束observable
,请执行end$.onNext("anything you want here");
。在这种情况下,结束事件由您生成。如果这是生成该事件的另一个源(按键等),那么您可以直接将从该源派生的observable作为takeUntil
的参数。
文档:
答案 1 :(得分:2)
对我有用的是使用take()运算符。它将在x个事件之后触发完整的回调。因此,通过传递1,它将在第一个事件之后完成。
打字稿:
private preloadImage(url: string): Observable<Event> {
let img = new Image();
let imageSource = Observable.fromEvent(img, "load");
img.src = url;
return imageSource.take(1);
}
答案 2 :(得分:1)
我认为你要找的是dispose()
方法。
请注意,subscribe方法返回一个Disposable,以便您可以取消订阅序列并轻松处理它。当您在可观察序列上调用dispose方法时,观察者将停止侦听可观察数据。通常,除非需要提前取消订阅,或者源可观察序列的寿命比观察者长,否则不需要显式调用dispose。 Rx中的订阅设计用于不使用终结器的即发即弃场景。请注意,Observable运算符的默认行为是尽快处理订阅(即,发布onCompleted或onError消息时)。例如,代码将x订阅序列a和b。如果抛出错误,x将立即取消订阅b。
答案 3 :(得分:1)
原始答案有点复杂,我找到了一种更简单的方法,方法如下:
const subscription$ = interval(1000).pipe(
finalize(() => console.log("End")),
).subscribe();
setTimeout(() => {
subscription$.unsubscribe();
}, 4000);
完成订阅也会在退订时触发。