網站搜尋

angular - 在 TypeScript Promise 中捕捉錯誤


Angular2 對於鏈式 promises 提供了非常有用的錯誤捕捉機制。然而,通常的情況(至少對我來說)是從前一個 promise 的 resolve 處理器內部調用 promises。這是因為需要在開始下一個 promise 之前處理資訊。例如:

this.d( "facebookOAuthLogin() - starts" );
this.fbProvider.login().then(
    ( loginResponse: { status: string, authResponse: any, accessToken: string, expiresIn: string, session_key: string, sig: string, userID: string } ) =>
    {
        this.d( "facebookOAuthLogin() - fbProvider.login() succeeded" );
        Config.config.sessionToken = loginResponse.authResponse.accessToken;
        this.fbProvider.getCurrentUserProfile().then(
            ( profileData : { email: string, name: string } ) =>
            {
                this.d( "facebookOAuthLogin() - fbProvider.getCurrentUserProfile() succeeded" );
                Config.config.user_email = profileData.email;
                Config.config.user_name = profileData.name;
                this.fbProvider.getUserPicture().then(
                    ( pictureData : { data:{ is_silhouette: boolean, url: string, width: number, height: number } } ) =>
                        {
                            this.d( "facebookOAuthLogin() - fbProvider.getUserPicture() succeeded" );
                            // this.facebook_picture_url = pictureData.data.url;
                            // this.facebook_picture_is_silhouette = pictureData.data.is_silhouette;
                            if( pictureData.data.is_silhouette || pictureData.data.url == null )
                            {
                                this.d( "facebookOAuthLogin() - pictureData.data.url == null" );
                                Config.config.jpegBase64Data = null;
                                this.afterFacebookLogin();
                            }
                            else
                            {
                                this.d( "facebookOAuthLogin() - pictureData.data.url != null" );
                                ImageStore.readToData( pictureData.data.url ).then(
                                    dataBase64 =>
                                    {
                                        this.d( "facebookOAuthLogin() - facebook picture read successfully" );

所以,問題是——如果我想以最簡單的方式捕捉所有處理程序中的所有錯誤(我們先不討論異常類型——假設我只需要記錄錯誤並回報。任何錯誤——而不單獨處理它們。)

據我所知,在代碼周圍使用 try{}catch(err) 不會捕捉從 Promise 處理程序中拋出的錯誤。

使用上面的程式碼——我是否需要在每個 Promise 處理器中添加 try/catch,還是可以使用外部(第一個)Promise 的 .catch() 方法?

答案#1

鏈接 Promise 的一種方法是在 then 函數內返回一個 Promise,像這樣:

method1()
  .then(response1 => {
    // ... do something
    return method2(response1);
  })
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())

當所有承諾如預期般成功解決時,所有方法會依序被呼叫(method1 -> method2 -> method3 -> handleFinally)。

當一個 promise 失敗時,所有後續的 promise 都會被跳過,並且改為調用 catch。假設 method2 失敗,我們有這個調用鏈:method1 -> method2 -> handleError -> handleFinally。

現在假設我們想忽略 method2 中的錯誤,我們可以為這個調用添加一個 catch 語句:

method1()
  .then(response1 => {
    // ... do something
    return method2(response1)
      .catch(error2 => silentlyHandleError(error2));
  })
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())

請注意,catch 不應放在主要的 Promise 鏈中。下一個區塊會多解釋一些內容:

method1()
  .then(response1 => {
    // ... do something
    return method2(response1);
  })
  .catch(error => silentlyHandleError(error)) // catchs error1 and error2
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())