簡體   English   中英

鏈接Angular Promise拒絕

[英]Chaining Angular promise rejections

我有一個鏈接的諾言,如果對任何一個諾言都被拒絕,則需要執行一個異步操作(獲取翻譯后的錯誤消息)。 由於我已經獲得了成功的連鎖承諾,因此我認為也無法連鎖拒絕-我試圖簡單地嵌套異步調用,但是我沒有從deferred.reject(deferredRejection.promise);獲得解決的承諾deferred.reject(deferredRejection.promise); 下面。 指針表示贊賞!

login: function(email, password) {
  var deferred = $q.defer();
  AuthService.login(email, password).then(function(response) {
    var user = {
      'accountToken': response.accountToken,
      'email': response.username,
      'onboarded': response.onboarded,
      'verified': response.verified
    };          
    return SyncStorageService.write(SyncStorageService.storageKeys.user, 
        user);  
  }, function(error) {
    // login failed
    var deferredRejection = $q.defer();
    $translate('ALERTS.LOGIN_FAILED').then(function(translatedValue) {
      deferredRejection.resolve(translatedValue);
    });
    deferred.reject(deferredRejection.promise);
  }).then(function(data) {
    deferred.resolve(data);
  }, function(error) {
    // saving data failed
    var deferredRejection = $q.defer();
    $translate('ALERTS.UNKNOWN').then(function(translatedValue) {
      deferredRejection.resolve(translatedValue);
    });
    deferred.reject(deferredRejection.promise);
  });
  return deferred.promise;
}

更新的解決方案:

根據下面的答案,我能夠如下重寫代碼:

login: function(email, password) {
  return AuthService.login(email, password).then(function(response) {
    return {
      'accountToken': response.accountToken,
      'email': response.username,
      'onboarded': response.onboarded,
      'verified': response.verified
    };
  }).then(function(data) {
    return SyncStorageService.write(SyncStorageService.storageKeys.user, 
        data);
  });
}

筆記:

  • AuthService.loginSyncStorageService.write現在都拒絕帶有Error對象的承諾(例如new Error('ALERT.ERROR_MESSAGE'); ),該承諾會通過login到控制器而冒泡(以前是在服務級別進行轉換);
  • 調用login方法的控制器具有.catch() .then().catch()塊-在.catch()上,翻譯並顯示傳遞的Error.message

看來您並沒有真正地鏈接諾言,而是使用了被遺忘的諾言/遞延反模式 對您實際希望它的行為進行一些假設,並排除對$translate的調用,那么我想像的是以下內容:

login: function(email, password) {
  return AuthService.login(email, password).then(function(response) {
    return {
      'accountToken': response.accountToken,
      'email': response.username,
      'onboarded': response.onboarded,
      'verified': response.verified
    };          
  }, function() {
    return $q.reject('ALERTS.LOGIN_FAILED');
  }).then(function(user) {
    return SyncStorageService.write(SyncStorageService.storageKeys.user, user).catch(function() {
      return $q.reject('ALERTS.UNKNOWN');
    });
  }).catch(function(message) {
    return $translate(message).then(function(translatedValue) {
      return $q.reject(translatedValue);
    });
  });
}

要記住的主要內容是:

  • 如果您確實要拒絕派生的$q.reject(error)從成功或錯誤回調中返回$q.reject(error)

    上面所有的錯誤回調都可以做到這一點。 嘗試登錄或保存后的密碼使用翻譯密鑰作為錯誤,最終將傳遞給最終的catch回調。 $translate的成功回調也將其已解決的承諾轉換為被拒絕的承諾,因此最終的catch回調返回被拒絕的承諾,因此調用代碼獲得被拒絕的承諾,並(大概)向用戶顯示已翻譯的錯誤。

  • 如果您確實想解決派生的諾言,請從成功或錯誤回調中返回不是諾言的任何內容。 派生的諾言將用該值解決。 (如果沒有顯式的返回值,則包括undefined )。

    上面是在第一個回調中返回用戶return {'accountToken'....時完成的。

  • 如果要推遲對承諾的解決/拒絕,請從成功或錯誤回調中返回另一個承諾。 然后,以其他方式解決/拒絕其他方式最終解決或拒絕派生的承諾。

    這是上面在返回SyncStorageService.write...時和在返回$translate(...時)所做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM