我使用JQuery' $.when
和$.get
来获取一些数据并对其进行操作。当获取它或使用它执行某些操作时出错时,我想处理该错误,并以不同处理它,具体取决于我获取的数据/我在哪个路径获取它。
不幸的是,传递给$.when().fail(...)
的信息很少,并且不包含该信息。我怎么可能以非hacky [1]的方式从延期中冒出那些信息呢?
$.when(get(path1), get(path2)
.done(function(parsed1, parsed2) {
// do something with this date
}).fail(function(jqXHR, statusTxt, errTxt) {
// do something depending on which path failed...
});
function get(path) {
var parser = U.parser();
return $.get('/getter' + path)
.then(function(data) {
return parser(data);
});
}
[1]:当然,我可以关闭路径和一些我想要处理失败的全局对象,并在.fail()
返回的延迟$.get
处理它。我也可以通过一个没有失败的延期,但以某种方式包装失败,但这也感觉非常hacky。
答案 0 :(得分:3)
由于jqXHR对象是传递回$.when()
的内容之一,因此您似乎可以在其中放置与您的请求相关的内容。例如,如果路径是您想要的,您可以这样做:
function get(path) {
var parser = U.parser();
var p = $.get('/getter' + vcfPath)
.then(function(data) {
return parser(data);
});
p.myPath = path;
return p;
}
然后,在$.when()
处理程序中,您将拥有可以从中提取参数的jqXHR对象。
注意,$.when()
会在任何单个请求拒绝后立即拒绝。如果您确实希望所有请求都继续,并且您想知道所有请求何时已满(无论已解决还是已拒绝),则无法使用$.when()
。 jQuery本身不提供该功能。你可以自己构建它或使用提供它的外部promise库(我使用具有Promise.settle()
的Bluebird。
这是一个有效的例子:
var data = {
json: JSON.stringify({
text: 'some text',
array: [1, 2, 'three'],
}),
delay: 1
}
function runAjax(data, value) {
var p = $.ajax({
url:"/echo/json/",
data:data,
type:"POST",
});
// put something on the jqXHR object for retrieval later
p.myData = value;
return p;
}
function runAjaxFail(data, value) {
var p = $.ajax({
url:"/echo/junk/",
data:data,
type:"POST",
});
// put something on the jqXHR object for retrieval later
p.myData = value;
return p;
}
$.when(runAjax(data, "Hello"), runAjax(data, "GoodBye"), runAjaxFail(data, "My Fail Message")).then(function(r1, r2) {
// for each arg [0] is data, [1] is status, [2] is jqXHR object
log(r1[2].myData); // logs "Hello"
log(r2[2].myData); // logs "GoodBye"
}, function(jqXHR, textStatus, errorThrown) {
// fail handler
log("fail: " + jqXHR.myData);
});
工作演示:http://jsfiddle.net/jfriend00/g8z353cz/
这是承诺世界完全支持的另一种方法。这将接管ajax promise的解析,以便您可以准确地输入所需的任何数据。在这个特定的实现中,我选择始终解析并仅使用已解析值中的数据来告诉您哪些ajax调用成功或失败,但如果您愿意,也可以使用带有值的拒绝。这保证会一直传播:
function get(path) {
var parser = U.parser();
var d = $.Deferred();
$.get('/getter' + path)
.then(function(data) {
d.resolve(parser(data));
}, function(jqXHR) {
// error handler
d.resolve({path: path, jqXHR: jqXHR});
});
return d.promise();
}
而且,您可以在此处看到此类实施:http://jsfiddle.net/jfriend00/c0u40gqh/
答案 1 :(得分:0)
尝试
注意,在第一个error
停止,但可以为此实施解决方法。以下主要针对可能的自定义错误模式
var data = {
"path1" : function() { return {"path1" : [1,2,3]} },
"path2" : function() { return {"path2" : [7, 8, 9] }},
"path1Error" : function() {
console.log("path1 error")
},
"path2Error" : function() {
console.log("path2 error")
}
};
$.ajaxSetup({
beforeSend: function(jqXHR, settings) {
var path = JSON.parse(
decodeURIComponent(settings.data.split("=")[1])
);
jqXHR.path = (path + "Error") in data
? data[path + "Error"]
: path + "Error";
}
});
$.when(get("path1"), get("path2"))
.done(function(parsed1, parsed2) {
//console.log(parsed1, parsed2)
// do something with this date
})
.fail(function(jqXHR, statusTxt, errTxt) {
jqXHR.path()
// do something depending on which path failed...
});
function get(path) {
var parser = function (p) { return data[p]()};
// `error`
return $.post("/echo/jsons/", {json:JSON.stringify([path]) })
.then(function(data) {
return parser(data[0]);
});
}