facebook - Observable switch/flatMap 立即触发

标签 facebook angular rxjs

我的服务中有以下代码:

public loginWithFacebook(): Observable<any> {
    console.log('Login');
    return Observable.fromPromise(this.fb.login()).flatMap((userData) => {
      return this.http.post(authFacebook, {access_token: userData.authResponse.accessToken}, { observe: 'response' });
    }).do( (response: HttpResponse<any>) => {
      const token = response.headers.get('x-auth-token');
      if (token) {
        localStorage.setItem('id_token', token);
      }
    });
  }

  getFacebookProfile():Observable<any> {
    console.log("Get Profile");
    return Observable.fromPromise(this.fb.getLoginStatus())
        .filter((state) => state.status === 'connected')
        .switchMapTo(Observable.fromPromise(this.fb.api('/me')));
  }

后来我在我的组件中使用它来在登录成功后获取个人资料信息。

this.profileData = this.usersService.loginWithFacebook()
    .flatMapTo(this.usersService.getFacebookProfile());

但是,由于某种原因,甚至在登录过程完成之前 getFacebookProfile() 就会立即触发。我收到身份验证错误。另外,我必须登录两次才能显示个人资料信息。

我一直认为 switchMap 和 flatMap 仅在前一个可观察值发出值后才切换到下一个可观察值。 我在这里做错了什么?

--编辑--

如果我订阅第一个 Observable 并在订阅中调用 getFacebookProfile() ,则一切正常。但我觉得这不是一个非常优雅的解决方案。

最佳答案

问题是 Promise 是急切的。当您编写可观察对象时,您正在调用 this.fb.login() ,并将返回的 Promise 传递到 fromPromise 中。

这意味着登录是在调用 loginWithFacebook 时启动的,而不是在其返回的可观察对象上调用 subscribe 时启动的。

如果您希望将 login 推迟到调用 subscribe 之前,您可以使用 defer :

public loginWithFacebook(): Observable<any> {
  console.log('Login');
  return Observable.defer(() => Observable.fromPromise(this.fb.login()))
    .flatMap((userData) => {
      return this.http.post(authFacebook, {
        access_token: userData.authResponse.accessToken
       }, { observe: 'response' });
    })
    .do( (response: HttpResponse<any>) => {
      const token = response.headers.get('x-auth-token');
      if (token) {
        localStorage.setItem('id_token', token);
      }
    });
}

有关使用可观察量和 Promise 的更多信息,请参阅 Ben Lesh 的文章:RxJS Observable interop with Promises and Async-Await

关于facebook - Observable switch/flatMap 立即触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47169421/

相关文章:

android - 尝试发布到 friend 墙时出现 OAuthException

Facebook - 沙盒帐户的自定义受众 ToS

iphone - 如何使用 facebook ios sdk 发出好友请求?

Angular :HttpInterceptor 没有捕捉到每个请求

angular - 我无法在 ubuntu 14.04 上为 angular-cli 安装最新版本

typescript - switchMap 结合 mergeMap

javascript - 没有引用句柄的订阅实例是否需要退订?

android - 如何检查用户是否使用 FB SDK 4.0 for Android 登录?

angular - ionic 4 : Cannot read property 'get' of undefined

angular - 类的 Set throws Cannot invoke an expression which type lacks a call signature using BehaviorSubject and Observable