如何在RxJS中完成Observable

时间:2015-12-04 20:47:54

标签: javascript stream observable rxjs reactivex

我们说我们有一个 Observable

var observable = Rx.Observable
    .fromEvent(document.getElementById('emitter'), 'click');

如何才能完成(所有订阅的观察员会触发 onComplete 事件)?

4 个答案:

答案 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()方法。

来自:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md#cold-vs-hot-observables

  

请注意,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);

完成订阅也会在退订时触发。