【问题标题】:How can I complete Observable in RxJS如何在 RxJS 中完成 Observable
【发布时间】:2016-03-09 21:45:14
【问题描述】:

假设我们有一个Observable

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

我怎样才能使它Complete(什么会为所有订阅的Observers触发onComplete事件)?

【问题讨论】:

    标签: javascript stream observable rxjs reactivex


    【解决方案1】:

    我为我的用例找到了一种更简单的方法,如果你想在 observable 完成时做某事,那么你可以使用这个:

    const subscription$ = interval(1000).pipe(
      finalize(() => console.log("Do Something")),
    ).subscribe();
    

    finalize 在完成时触发,当所有订阅都被取消订阅等时。

    【讨论】:

    • 只有当它的 refCount 低于 1 时才会完成 observable。这与显式完成 observable 不同。
    【解决方案2】:

    我认为您正在寻找的是dispose() 方法。

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

    请注意,subscribe 方法返回一个 Disposable,以便您可以取消订阅序列并轻松地处理它。当你在 observable 序列上调用 dispose 方法时,观察者将停止监听 observable 的数据。通常,您不需要显式调用 dispose,除非您需要提前取消订阅,或者当源 observable 序列的生命周期比观察者更长时。 Rx 中的订阅是为不使用终结器的即发即弃场景而设计的。请注意,Observable 运算符的默认行为是尽快处理订阅(即,当发布 onCompleted 或 onError 消息时)。例如,代码将 x 订阅序列 a 和 b。如果 a 抛出错误,x 将立即从 b 退订。

    【讨论】:

    • 如果问题是:如何取消订阅点击监听器的可观察对象,那么这个答案将适用。但问题是如何“完成”一个 observable$ - 根据 @dK 的 stackoverflow.com/a/52198997/3136861 Calling unsubscribe() itself does not call complete method
    • 是的,它需要自己完成一个可观察的流,但不仅仅是取消订阅可观察的流。
    【解决方案3】:

    对我有用的是使用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);
    }
    

    【讨论】:

    • first()可以代替take(1)
    【解决方案4】:

    在目前的形式中,你不能。您的 observable 源自未完成的源,因此它本身无法完成。您可以做的是使用完成条件扩展此源。这将像:

    var end$ = new Rx.Subject();
    var observable = Rx.Observable
        .fromEvent(document.getElementById('emitter'), 'click')
        .takeUntil(end$);
    

    当你想结束observable时,你做end$.onNext("anything you want here");。在这种情况下,结束事件是由您生成的。如果这是另一个产生该事件的源(按键等),那么您可以直接将一个从该源派生的可观察对象作为takeUntil 的参数。

    文档:

    【讨论】:

    • 这似乎是浏览器应用程序内存泄漏的潜在危险。似乎可以有无限数量的观察者与已经从范围中删除的 HTML 元素连接。它可能会阻止 GC 从内存中删除这些元素以及许多其他 refs……
    • ??我不跟着你。这是什么'?无论如何,onCompleted 处理程序将为所有观察者触发,这就是您所要求的。关于内存泄漏,当最后一个观察者取消订阅 fromEvent 创建的 observable 时,将删除创建的事件监听器。
    • “什么将为所有订阅的观察者触发 onComplete 事件”是我问题的第二个附加部分。我需要实现的是删除事件监听器。 Observable 完全完成,因此当我不再监听事件时,我可以删除所有过时的引用。
    • > 关于内存泄漏,当最后一个观察者取消订阅fromEvent 创建的可观察对象时,创建的事件监听器将被删除。哦-这就是使您的回答真正有用的原因。谢谢 ;)
    • 这仍然是解决这个问题的合适方法吗?我正在尝试设计一种方法来创建取消令牌以取消“取消”方法调用上的多个可观察对象。
    猜你喜欢
    • 2020-03-26
    • 1970-01-01
    • 2017-06-14
    • 2021-11-16
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    相关资源
    最近更新 更多