【问题标题】:how to cancel RXJS subscribe after a while如何在一段时间后取消 RXJS 订阅
【发布时间】:2017-12-13 12:56:39
【问题描述】:

如果用户的网速很慢并且订阅时间过长(超过 30 秒),我想取消它。

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

           //some instructions

        },
        error => alert(error),
        () => console.log("finished"));
}
k.unsubscribe();

【问题讨论】:

    标签: javascript firebase rxjs observable


    【解决方案1】:

    查看Operators 文档,您会发现很多有趣的东西。

    只需使用专门针对这种情况的Timeout 运算符:

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

    timeout 将等待一个值发出直到时间限制,此时它将以失败结束可观察对象。

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

    更新: 显然,Firebase 客户端在接收到值后保持可观察对象运行(大概是为了让您收到进一步更新的通知)。而且由于 Observable 永远不会完成,Timeout 将在接收数据后 30 秒(或任何您传递的持续时间)后执行,从而导致流失败。

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

    this.firebase(user)
        .take(1)
        .timeout(wait)
        .subscribe(/* etc */);
    

    【讨论】:

    • 即使用户在 5 秒后获得数据,错误警报也会始终显示。超时后我收到此错误:TimeoutError:Timeout has occured.
    • @user2243952 啊,我明白了,显然 Firebase 即使在接收到之后也会保持其 observable 打开(因此,当然,您可以稍后接收更新的数据)。尝试使用.take(1).timeout(...)so that it completes with success after a single event。
    • 非常感谢!但这是否意味着 Firebase observable 在第一次尝试后停止,即使超时尚未结束?
    • @user2243952 不,没有“尝试”。 firebase 返回的 observable 每次更改时都会输出一个值。 take 将只通过一次更改,并立即“完成”流。 timeout 将等待 30 秒,如果在此之前发生了发射,它将成功,否则将失败。但是请记住,流在发出后就结束了,所以超时会看到永远不会有更多的数据进来,也不会出错。
    • 感谢您详细而清晰的解释。很有帮助
    【解决方案2】:

    您可以使用计时器操作符创建另一个 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( ... )
    

    【讨论】:

    • 我想在时间 > 30000 时显示警报。我怎么知道超过了时间?
    • 是的,@Kroltan 回答 ^ 更适合这个用例。很高兴知道该运算符的存在!感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 2018-07-29
    • 2016-12-20
    • 2017-03-26
    • 2020-10-28
    相关资源
    最近更新 更多