我会无条件地发出Ajax请求,并且通常以相同的方式处理错误。所以例如如果发生404,则默认情况下,我只会显示标准错误消息。但是在某些情况下,我还想做其他事情。
注意:我正在使用ExtJS 4来执行实际的Ajax请求,但这不是特定于ExtJS的问题。 ExtJS不使用Promises,因此我基本上是将其API转换为Promise API。
这是代码:
var defaultErrorHandler = function(response) {
// do some default stuff like displaying an error message
};
var ajaxRequest = function(config) {
return new Promise(function(fulfill, reject) {
var ajaxCfg = Ext.apply({}, {
success: function(response) {
var data = Ext.decode(response.responseText);
if (data.success) {
fulfill(data);
} else {
defaultErrorHandler(response);
reject(response);
}
},
failure: function(response) {
defaultErrorHandler(response);
reject(response);
}
}, config);
Ext.Ajax.request(ajaxCfg);
});
};
// usage without special error handling:
ajaxRequest({url: '/some/request.json'}).then(function(data) {
// do something
});
// usage with special error handling:
ajaxRequest({url: '/some/request.json'}).then(function(data) {
// do something
}, function(response) {
// do some additional error handling
});
现在的问题:“没有特殊错误处理的用法”不起作用,因为如果我不提供拒绝功能,它将引发错误。为了解决这个问题,我被迫提供一个空函数,如下所示:
// usage without special error handling:
ajaxRequest({url: '/some/request.json'}).then(function(data) {
// do something
}, function() {});
每次都提供一个空函数(在我的代码库中,这将是数百次)很丑陋,所以我希望有一个更优雅的解决方案。
我也不想使用catch(),因为那样会捕获所有抛出的错误,即使它发生在fulfill函数中。但是我的代码中发生的实际错误不应该处理,应该出现在控制台中。
答案 0 :(得分:0)
除非您希望提供一个未处理的拒绝处理程序,否则没有“所有承诺的默认错误处理程序”这样的东西。但是,这不仅限于您对ajax请求的承诺。
最简单,最好的解决方案是仅公开您的defaultErrorHandler
,并让每个调用者根据您的诺言明确向其传递then
调用。如果他们不想使用它,他们要么需要提供自己的特殊错误处理程序,要么会被拒绝。该解决方案提供了最大的灵活性,例如允许进一步处理拒绝。
如果这不是您想要的,而是需要立即处理ajax错误,那么最好的选择是覆盖所返回的promise的then
方法:
function defaultingThen(onfulfill, onreject = defaultErrorHandler) {
return Promise.prototype.then.call(this, onfulfill, onreject);
}
function ajaxRequest(config) {
return Object.assign(new Promise(function(resolve, reject) {
Ext.Ajax.request({
...config,
success: function(response) {
var data = Ext.decode(response.responseText);
if (data.success) {
resolve(data);
} else {
reject(response);
}
},
failure: reject,
});
}), {
then: defaultingThen,
});
}