如果在超时时间内没有next(...)调用,请重试(重新订阅)可观察到的源

时间:2018-06-30 17:21:00

标签: javascript timeout rxjs observable retry-logic

我正在尝试使rxjs源可观察到,它表示将数据推送给我的网络连接,如果在超时时间内未收到数据,则重新连接(通过重新订阅源可观察到)。我当然可以用一种有点怪异的方式编写此代码,但是有没有一种很好的方法可以使用rxjs简洁地编写此代码?

1 个答案:

答案 0 :(得分:0)

我最终写了一个运算符。我认为有一种更好的方法可以做到这一点,但是看到其他人也没有一个想法,这就是我写的可管道运算符:

import { Observable, Subscription } from "rxjs";

export function retryAfterTimeout<T>(timeout: number, allowCompletion = false): (obs: Observable<T>) => Observable<T> {
    return source => new Observable<T>(observer => {
        let sub: Subscription | undefined;
        let timer: number | undefined;

        function resetTimer() {
            if (timer) clearTimeout(timer);
            timer = window.setTimeout(() => resub(), timeout);
        }

        function resub() {
            if (sub) sub.unsubscribe();
            sub = source.subscribe({
                next(x) {
                    resetTimer();
                    observer.next(x);
                },
                error(err) {
                    observer.error(err);
                },
                complete() {
                    if (allowCompletion)
                        observer.complete();
                    else
                        resub();
                }
            });
        }

        resub();
        resetTimer();

        return () => {
            if (sub) sub.unsubscribe();
            if (timer) window.clearTimeout(timer);
        };
    });
}