2016-12-27 22 views
0

我正嘗試使用REDX傳奇實現Google OAuth 2。如何通過REDX傳奇處理Google OAuth流程

我有我的傳奇觀察者監聽GOOGLE_AUTH動作,然後執行googleLogin

function *watchGoogleAuth() { 
    yield *takeLatest(GOOGLE_AUTH, googleLogin) 
} 

function *googleLogin() { 
    const id_token = yield call(GoogleSignIn); 
    console.log(id_token); 
    const response = yield call(HttpHelper, 'google_token', 'POST', id_token, null); 
    console.log(response); 
} 

GoogleSignIn的實現是在apis.js

export function GoogleSignIn() { 
    const GoogleAuth = window.gapi.auth2.getAuthInstance(); 

    GoogleAuth.signIn({scope: 'profile email'}) 
     .then(
     (res) => { 
      const GoogleUser = GoogleAuth.currentUser.get(); 
      return { 
      id_token: GoogleUser.getAuthResponse().id_token 
      }; 
     }, 
     (err) => { 
      console.log(err) 
     } 
    ) 
} 

但傳奇似乎並沒有等待GoogleSignIn來完成。只要OAuth同意屏幕彈出,傳奇繼續執行console.log而不等待谷歌登錄承諾返回實際數據。

有沒有更好的方法來處理這種情況?謝謝!

+1

GoogleSignIn函數應該返回promise –

回答

1

要擴展@ HenrikR的答案,生成器不會等待,除非它收到承諾。

export const GoogleSignIn =() => { 
    const GoogleAuth = window.gapi.auth2.getAuthInstance(); 

    return new Promise((resolve, reject) => { 
    GoogleAuth.signIn({scope: 'profile email'}) 
     .then(
     (res) => { 
      const GoogleUser = GoogleAuth.currentUser.get(); 
      resolve(GoogleUser.getAuthResponse().id_token); 
     }, 
     (err) => { 
      reject(err) 
     } 
    ); 
    }); 
} 

因此,您應該將yield語句包裝在try/catch中。簡化且有些懶惰:

function *googleLogin() { 
    try { 
    const id_token = yield call(GoogleSignIn); 
    if (id_token) { /* Possibly with more checks and validations */ 
     console.log(id_token); 
     const response = yield call(HttpHelper, 'google_token', 'POST', id_token, null); 
     console.log(response); 
    } 
    } catch (e) { 
    console.log(e); 
    } 
}