[英]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.login
和SyncStorageService.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.