一段时间后如何取消RXJS订阅

use*_*952 3 javascript observable rxjs firebase

如果用户的互联网速度很慢且订阅时间太长(超过30秒),我想取消它.

const k = this.firebase(user)
        .subscribe(data => {

           //some instructions

        },
        error => alert(error),
        () => console.log("finished"));
}
k.unsubscribe();
Run Code Online (Sandbox Code Playgroud)

Kro*_*tan 8

查看操作员文档,您会发现许多有趣的事情.

只需使用Timeout运算符,该运算符专门用于此情况:

const k = this.firebase(user)
    .timeout(30 * 1000)
    .subscribe(
        data => { /* do stuff*/ },
        error => { /* handle it */ },
        () => { /* finished */ }
    );
Run Code Online (Sandbox Code Playgroud)

timeout将等待被发射的值达到了时间限制,在该点它将结束观察到有故障.

这意味着error如果在30秒内没有收到任何内容,将调用处理程序,如果需要,您可以使用它来通知用户.

更新:显然Firebase客户端在收到值后保持可观察的运行(可能是因为您收到进一步更新的通知).由于Observable永远不会完成,因此Timeout将在收到数据后的秒数(或任何您作为持续时间传递的任何内容)之后执行操作,从而导致流失败.

要将"流"Observable转换为单事件Observable,在超时前使用Take运算符:

this.firebase(user)
    .take(1)
    .timeout(wait)
    .subscribe(/* etc */);
Run Code Online (Sandbox Code Playgroud)

  • @ user2243952啊,我看到,显然Firebase即使在收到后仍保持其可观察的开放状态(当然,您可以稍后收到更新的数据).尝试使用`.take(1).timeout(...)`[以便在单个事件后成功完成](http://reactivex.io/documentation/operators/take.html). (2认同)

小智 6

您可以使用计时器运算符创建另一个 Observable 流并监听流 k 直到计时器流完成。

前任:

const timer$ = Observable.timer(30000) // time in ms
const k$ = this.firebase(user)
    .takeUntil(timer$) // subscribe to k$ until the timer$ finishes
    .subscribe( ... )
Run Code Online (Sandbox Code Playgroud)