我有一个链式承诺,如果拒绝任何一个承诺,我需要执行异步操作(获取翻译的错误消息)。由于我已经获得了成功的链式承诺,我认为它不可能在拒绝时链接 - 我试图简单地嵌套异步调用,但我没有得到解决的承诺从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
方法的控制器具有.then()
和.catch()
块 - 在.catch()上,传递的Error.message
被翻译并显示。答案 0 :(得分:2)
看起来你并没有真正链接承诺,而是使用the forgotten promise/deferred anti pattern。做一些关于你实际上希望它如何表现的假设,并将对$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)
。
上面的所有错误回调都是这样做的。尝试登录或保存后使用翻译密钥作为最终将传递给最终catch
回调的错误。来自$translate
的成功回调也是为了将其已解决的承诺转换为被拒绝的承诺,因此最终的catch回调返回被拒绝的承诺,因此调用代码获得被拒绝的承诺,并且(可能)显示已转换的错误用户。
如果您肯定想要解决派生的承诺,请返回任何不是成功或错误回调的承诺。派生的承诺将使用该值解决。 (如果您没有明确的返回值,则包括undefined
。)
这是在第一次回调中返回用户return {'accountToken'....
时执行的操作。
如果您想推迟解析/拒绝承诺,请从成功或错误回调中返回另一个承诺。然后,派生的承诺最终将以解决/拒绝其他承诺的任何方式得到解决或拒绝。
这是以上在返回SyncStorageService.write...
时以及返回$translate(...
时所做的事情。