我正在尝试创建一个可观察的facebook jsdk,所以我有一个方法,.create()
d observable看起来像这样
getLoginStatus$() {
return Observable.create((observer: Observer<FBResponseObject>) => {
try {
// this._fb is window.FB
this._fb.getLoginStatus((resp: FBResponseObject) => {
if (resp.error) {
observer.error(resp.error);
} else {
observer.next(resp);
observer.complete();
}
}, force);
} catch (error) {
observer.error(error);
}
return function () {};
});
}
问题是,由于facebook sdk是异步加载的,所以在我订阅此方法时它可能仍然不可用。所以我有一个Subject
fbSdkReady$
next()
我true
到getLoginStatus$
一旦可用。现在问题是如何连接这些,所以当我订阅fbSdkReady$
时,它首先等待delayWhen(() => fbSdkReady$.filter(r => !!r)
准备就绪,然后才创建可观察的。
我尝试使用fbSdkReady$
,它可以正常等待Observable.create
准备就绪,但FB
仍被称为immeditealy,因此错误消失,因为{{1}}仍然还没准备好。
我可以做些什么来推迟创造那个可观察的?
答案 0 :(得分:1)
您已有fbSdkReady$
。但是,如果我理解正确,它只会在sdk加载一次后才会发出。这是一个问题,因为如果您以后订阅它,您将错过加载事件,并且不知道您是否需要等待更长时间或者是否已经屈服。一旦可用,您应该使流重复就绪值。您可以通过致电fbSdkReady$.cache(1)
来执行此操作,但由于它受主题支持,您也可以将其替换为new Rx.replaySubject(1)
。
现在我们已经解决了这个问题,你可以使用fbSdkReady$
作为getLoginStatus$()
的基础。
fbSdkReady$.switchMap(() => getLoginStatus$())
注意我使用了switchMap
,因为它清楚地表明只有getLoginStatus$()
个实例在任何时候都有效。但由于您的来源只发出一次,您还可以使用mergeMap
或flatMap
。
聚苯乙烯。我希望你也可以就这个问题致电complete()
,而不仅仅是next()
。优良作法是向Observable发出信号,表明你已经完成了它们。