【问题标题】:How to use a default reject handler in Promise如何在 Promise 中使用默认拒绝处理程序
【发布时间】:2019-03-19 17:36:45
【问题描述】:

我使用 Promise 发出 Ajax 请求,并且通常以相同的方式处理错误。所以例如如果发生 404,那么默认情况下我只会显示标准错误消息。但在某些情况下,我想做其他事情。

注意:我使用 ExtJS 4 来执行实际的 Ajax 请求,但这个问题并不是 ExtJS 特有的。 ExtJS 不使用 Promise,所以我基本上是将他们的 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(),因为它会捕获所有抛出的错误,即使它发生在完成函数中。但是我的代码中发生的实际错误不应该被处理,它们应该出现在控制台中。

【问题讨论】:

  • 您可以编写一个特殊的错误处理函数,如果错误不是特殊的,它将不执行任何操作,然后将该函数传递给拒绝块。这样你就不必每次都传递空函数,而是每次都需要传递特殊的错误处理函数。

标签: javascript


【解决方案1】:

没有“所有承诺的默认错误处理程序”这样的东西,除非您希望提供一个未处理的拒绝处理程序。但是,这不仅限于对您的 ajax 请求的承诺。

最简单和最好的解决方案是只公开您的defaultErrorHandler,并让每个调用者根据您的承诺明确地将then 调用传递给它。如果他们不想使用它,他们要么需要提供自己的特殊错误处理程序,要么会得到一个被拒绝的承诺。该解决方案提供了最大的灵活性,例如允许在链条的下游处理拒绝。

如果这不是您想要做的,而是需要立即处理 ajax 错误,那么最好的办法是覆盖您返回的承诺的 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,
    });
}

【讨论】:

    猜你喜欢
    • 2015-04-24
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2016-11-06
    • 2019-07-21
    • 2016-11-10
    • 2017-04-23
    相关资源
    最近更新 更多