在过去的观察日里,我阅读了很多处理承诺的最佳实践。大多数帖子的一个中心点是:
因此,如果您在代码中编写[deferred]字样 [...],你做错了什么。1
在试验错误处理期间,我看到了一个意想不到的行为。当我链接承诺并且它进入第一个catch块时,第二个承诺得到解决而不被拒绝。
在此示例中,您会看到“我在这里,但这是一个错误”
function BaseService($http, $q) {
this.$http = $http;
this.$q = $q;
}
BaseService.prototype.doRequest = function doRequest() {
return this.$http({
method: 'GET',
url: 'not/exisint/url'
})
.then(function (response) {
// do some basic stuff
})
.catch(function(response) {
// do some baisc stuff e.g. hide spinner
});
}
function ChildService($http, $q) {
this.$http = $http;
this.$q = $q;
}
ChildService.prototype = Object.create(BaseService.prototype);
ChildService.prototype.specialRequest = function specialRequest() {
return this.doRequest()
.then(function (response) {
alert('I am here but It was an error');
})
.catch(function (response) {
// do some more specific stuff here and
// provide e.g. error message
alert('I am here but It was an error');
return response;
});
}
通过此解决方法,您可以解决此问题,但您必须创建新的延迟。
BaseService.prototype.doRequest = function doRequest() {
var dfd = this.$q.defer();
return this.$http({
method: 'GET',
url: 'not/exisint/url'
})
.then(function (response) {
// do some basic stuff
dfd.resolve(response);
})
.catch(function(response) {
// do some basic stuff e.g. hide spinner
dfd.reject(error);
});
}
答案 0 :(得分:2)
您的解决方法几乎是正确的,您可以将其简化为以下内容:
BaseService.prototype.doRequest = function doRequest() {
return this.$http({
method: 'GET',
url: 'not/exisint/url'
})
.then(function (response) {
// do some basic stuff
return response;
}, function (error) {
return this.$q.reject(error);
});
}
$q.reject
是创建延迟的快捷方式,可立即被拒绝。
.then
或.catch
只是将返回值包装到新的承诺中。您可以返回被拒绝的承诺,以使.catch
链工作。您也可以采取相反的做法,例如当您想要在成功回调中拒绝承诺时出于某种原因:
function getData() {
return this.$http.get(endpoint).then(result => {
// when result is invalid for whatever reason
if (result === invalid) {
return this.$q.reject(result);
}
return result;
}, err => this.$q.reject(err));
}
getData().then(result => {
// skipped
}, error => {
// called
});
答案 1 :(得分:0)
只需添加到Dieterg's答案和解决方法,您还可以将代码包装到$ q构造函数中:
BaseService.prototype.doRequest = function doRequest() {
return $q(function (resolve, reject) {
$http.get('not/exisint/url').then(function (response) { // success
/* do stuff */
resolve(response);
}, function (error) { // failure
/* do stuff */
reject(error);
});
});
};