2

我正在使用 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()的 Deferred 上处理它。$.get我也可以传递一个没有失败但以某种方式包装失败的 Deferred ,但这也感觉很hacky。

4

2 回答 2

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().

这是一个工作示例:

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/


这是另一种在 Promise 世界中得到完全支持的方法。这接管了 ajax 承诺的解析,以便您可以将任何您想要的数据放入其中。在这个特定的实现中,我选择始终解析并仅使用解析值中的数据来告诉您哪些 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/

于 2014-10-22T23:19:22.373 回答
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/

于 2014-10-23T00:26:51.080 回答