gpt4 book ai didi

javascript - 阻止 JQuery promise 传播到包装器失败

转载 作者:行者123 更新时间:2023-11-30 14:50:13 25 4
gpt4 key购买 nike

我的应用程序有一堆 $.ajax 调用,其中大部分具有 .done.fail 函数。

我想围绕 Ajax 调用编写一个包装器,这样如果一个函数没有 .fail 函数,或者如果 .fail 函数没有处理一个给定的错误(例如它只处理 404,但我返回 403),然后我希望包装器将其作为后备处理。

这是我写的:

function DoAjax(fn, errorText) {
var deferred = $.Deferred();
var result = fn();
if (result === undefined)
throw 'Function passed into DoAjax has not returned a promise.';
result.always(function () {
deferred.resolve(result);
});
result.fail(function () {
alert('fail');
deferred.fail();
});
return deferred.promise();
}

它主要按照我的预期工作,除了失败将执行两次 - 一次在方法 DoAjax 中,另一次在 Ajax 调用的站点。

我这样执行 DoAjax:

DoAjax(function () {
var ajaxCall = $.ajax({
method: "GET",
url: baseUrl + "api/test"
});

ajaxCall.fail(function() { alert('failed the call'); });

return ajaxCall;
});

我相信我可以通过手动创建一个 $.deferred 然后围绕它调用 $.ajax 来实现这一点,但我宁愿没有另一个包装器来围绕它。

我正在使用 jQuery 2.2。

最佳答案

是时候进行一些核心学习了。需要注意几件事:

  1. .done().fail() 只是 jQuery.ajax() 选项,没有所谓的“过滤能力” .then(successCallback, errorCallback)(或 jQuery 3+ 中的 .then()/.catch())。换句话说,无论从 .done().fail() 回调中返回什么,都不会对 jqxhr promise 链产生下游影响。
  2. 在 jQuery <3 中,errorCallback 不会自动捕获错误。默认行为是保留在 promise 链的错误路径上。为了给出 errorCallback 'catch' 行为,您必须从中返回已解决的 promise 。在 jQuery 3+ 中,默认情况下会捕获 errorCallback,但您可以返回被拒绝的 promise 或抛出以传播错误条件。
  3. 在这种情况下,您的 fn() 返回 jqxhr,而不是结果。因此,如所写,if(result === undefined) 测试将始终返回 false。 jqxhr最终下发的结果不能这样测试。
  4. 如果您不确定一个函数是返回一个值还是一个 Promise,那么将返回的值/对象包装在 jQuery.when(...) 中,例如 $.when(fn ()).
  5. 处理 (3) 后,您可以直接从 jQuery.when(...) 返回的 promise 链接。不需要显式的 $.Deferred()

试试这个:

var baseUrl = '/';
function DoAjax(fn) {
return $.when(fn()) // no need to test for fn() not returning a promise. `$.when(fn())` forces any non-Promise to Promise.
.then(function(response) {
console.log('success!', response);
}).then(null, function(err) {
console.error('B', err); // (LOG_2)
});
}

DoAjax(function () {
return $.ajax({
method: "GET",
url: baseUrl + "api/test"
}).then(null, function(jqxhr, textStatus) {
var err = new Error('Whoops! ' + jqxhr.status + ': ' + textStatus);
console.error('A', err);

// "throw behaviour"
return err; // propagate the error (jQuery <3) or `throw err;` (jQuery 3+)

// "catch behaviour"
// return $.when('default response'); // "2" mutate failure into success (jQuery <3) or `return 'default response';` (jQuery 3+)
});
});

Fiddle

现在尝试换掉标记为“传播行为”和“捕获行为”的行并观察日志中的差异。

如果您没有立即得到它,请不要担心。学习这些东西需要时间。

如果你有选择,那么使用 jQuery 3+,其中 jqxhr 和其他 Promise 比 jQuery <3.

关于javascript - 阻止 JQuery promise 传播到包装器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48253972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com