从失败的JQuery jqXHR请求中获取更多信息

时间:2014-10-22 23:10:30

标签: jquery ajax jqxhr

我使用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。

2 个答案:

答案 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]);
    });
}

jsfiddle http://jsfiddle.net/guest271314/o3Lk73wg/