没有价值的超时可观察订阅

时间:2017-10-03 19:30:56

标签: angular ionic-framework firebase-realtime-database rxjs angularfire

我正在订阅来自Firebase的可观察返回值。如果连接出现问题,我希望订阅超时。这样做的正确方法是什么?我尝试了以下但是在收到最后一个值20秒后超时:

let chatSubscription = this.getChats().timeoutWith(20000, Observable.throw(new Error('timeout'))).subscribe(chats => { ... });

// edit:getChats()

getChats() {
        return Observable.create(observer => {
            let chatList = this.db.list('/users/' + this.auth.user.uid + '/chats').timeoutWith(20000, Observable.throw(new Error('timeout'))).subscribe(chats => {
                observer.next(chats);
            });  
            //keep track of this subscription
            this.openSubscriptions.push(chatList);  
        });
    }

2 个答案:

答案 0 :(得分:1)

您可以从初始超时的超时ObservableswitchMap开始,到第一个发出项目的原始值,例如:

const chats$ = this.getChats();
chats$.map(v => Observable.just(v))
      .startWith(Observable.never().timeoutWith(20000, new Error()))
      .switchMap(v => v)
      .subscribe(...);

如果在初始化的20s内发出一个值,switchMap只是身份运算符并继续提供原始值流中的项目。

答案 1 :(得分:1)

您可以使用race收听任何可观察到的东西:

const chats = this.db.list('/users/' + this.auth.user.uid + '/chats');
const timeout = Observable.throw(new Error("timed out")).delay(20000);
const chatWithTimeout = Observable.race(chats, timeout);
chatWithTimeout.subscribe(msg => ..., err => ...);

此外,您对Observable.create的使用似乎有点不正统。我建议您使用上述代码并将其用作getChats

getChats() {
    const chats = this.db.list('/users/' + this.auth.user.uid + '/chats');
    const timeout = Observable.throw(new Error("timed out")) .delay(20000);
    const chatWithTimeout = Observable.race(chats, timeout);
    return chatWithTimeout;
}

// usage
const subscription = foo.getChats().subscribe(...);

使用此版本,您无需保留开放订阅列表。让观察者自己跟踪这个订阅。