2016-09-13 11 views
0

Я пытаюсь создать наблюдаемую facebook JSDK, поэтому у меня есть метод, с .create() d наблюдаемым, что выглядит, например, как этотrxjs5: отложим создание наблюдаемой до другого наблюдаемого излучает определенное значение

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 загружается асинхронно, он может быть недоступен в момент подписания этого метода. Поэтому у меня есть fbSdkReady$ I next() до true после того, как он станет доступен. Теперь вопрос заключается в том, как подключить их, поэтому, когда я подписываюсь на getLoginStatus$, он сначала ждет fbSdkReady$, чтобы стать готовым и только затем создает наблюдаемый.

Я попытался с помощью delayWhen(() => fbSdkReady$.filter(r => !!r), который прекрасно работает для ожидания fbSdkReady$ быть готовым, но Observable.create называется immeditealy тем не менее, и, таким образом, ошибки аутов, потому что FB все еще не готов.

Что я могу сделать, чтобы отложить создание наблюдаемого?

ответ

1

У вас уже есть fbSdkReady$. Однако, если я правильно вас понимаю, он будет выдаваться только после того, как sdk будет загружен один раз. Это проблема, потому что, если вы подписались на нее позже, вы пропустили бы событие загрузки и не узнаете, нужно ли ждать дольше или если оно уже было получено. Вы должны заставить поток повторить готовое значение, когда оно доступно. Вы можете сделать это, позвонив fbSdkReady$.cache(1), но так как он подкреплен предметом, вы также можете заменить его new Rx.replaySubject(1).

Теперь мы получили это в сторону, вы можете просто использовать fbSdkReady$ в качестве базы для getLoginStatus$().

fbSdkReady$.switchMap(() => getLoginStatus$()) 

Примечание Я использовал switchMap, потому что ясно сообщается будет только один раз экземпляр getLoginStatus$() активизирован в любое время. Но поскольку ваш источник испускает только один раз, вы также можете использовать mergeMap или flatMap.

Ps. Надеюсь, вы также позвоните complete() по этому вопросу, а не только next(). Хорошая практика - сигнализировать Observables, что вы с ними работаете.

+0

Хорошо, это было намного проще, чем я думал. Я искал сложности там, где их не было. Благодаря! – foxx

+0

@foxx Не беспокойтесь, многие вещи в Rx легки, как только вы знаете точные операторы. Просто продолжайте учиться, и скоро вы тоже узнаете все трюки;) – Dorus