【问题标题】:Can someone explain clearly how jQuery.when() and deferred.then() works?有人可以清楚地解释 jQuery.when() 和 deferred.then() 的工作原理吗?
【发布时间】:2012-02-14 11:51:46
【问题描述】:

我正在开发一个 Web 应用程序,我需要加载一些文件 $.ajax。我在 $.when().then() 中发现了一些有趣的东西。

当我对请求返回的数据没有任何特殊关系时,它非常有用,如下例所示:

$.when(
    $.getScript('js/script1.js'),
    $.getScript('js/script2.js')
).then(function(){
    // Do whatever I want once both scripts are loaded...
});

如果我有一个这样的 ajax 请求时效果很好:

$.when(
    $.ajax('xml/myxml.xml')
).then(function(data){
    // Here I can work with data like I would with a regular ajax request
    alert($(data).find('mynode').text());
})

但如果我尝试以下操作,我将无法正常工作:

$.when(
    $.ajax('xml/myxml.xml'),
    $.getScript('js/script.js')
).then(function(data){
    // But here, I can't access $(data).find('mynode')...
})

我阅读了deferred object 页面,但其中大部分内容对我来说太技术性了,我无法理解在使用 $.when().then 时应该如何获取我的 ajax 数据() 从多个来源加载脚本和数据。

因此,如果有人可以帮助我了解如何在上面的测试用例中使用我的 ajax 数据,那就太好了!如果同时有人能以比官方 jQuery 文档更容易理解的方式解释延迟对象的事情,那就太棒了!

谢谢!

【问题讨论】:

  • 在这种情况下尝试检查 deferred.then 返回的参数。 console.log(arguments) 请发布结果。
  • 看这个页面上的例子:api.jquery.com/jQuery.when
  • 您的then 方法应该接受两个参数:.then(function(a1, a2) {....a1 将是第一个 ajax 调用的结果。 a2 将是 getscript 调用的结果。
  • @Ben Lee - 没必要。本质上,如果不包含第二个参数,则与使用 .done() 相同。
  • @Kevin B:console.log(arguments) 的结果太长,无法在此处发布...但它是一个数组,如果我理解正确我所看到的,看起来我有一个数组它的长度与我的 $.ajax 计数相同。所以我应该能够从那里获取我的 xml 数据...

标签: jquery jquery-deferred


【解决方案1】:

显然,对于每个延迟对象,至少如果它是一个 Ajax 请求,$.when 会将一个类似 [ "success", statusText, jqXHR ] 的参数传递给回调。 jqXHR 是一个表示 XMLHttpRequest 的对象(更多关于它的信息,请参见 $.ajax documentation)。所以以下应该工作:

$.when(
    $.ajax('xml/myxml.xml'),
    $.getScript('js/script.js')
).then(function(a){
    $(a[2].responseText).find('mynode');
});

请参阅$.when 文档中的第一个示例。

关于一般的延迟对象,this question 可能会有所帮助。

【讨论】:

  • .done() 的工作方式是否相同,因为您可能已经有一个演示来测试它?考虑到由于您还没有应用失败回调,因此使用 .done 而不是 .then 更有意义?
  • @KevinB:说实话我还没有测试过。完成会以相同的方式工作,你是对的,添加不同的成功和错误处理程序可能会更好。虽然我不知道这个论点在失败案例中的表现如何。可能是["error", statusText, jqXHR ],但我不确定(现在有时间测试一下)。
  • 感谢 Felix,您的回答让我走上了正轨,但 xml 数据的索引是 0,而不是 2...如果我这样做 $(data[0]).find('mynode ') 它有效...
  • @FelixKling:你能用 a[0] 而不是 a[2] 来改变你的答案吗?目前,您的代码无法正常工作,但通过该更改它会起作用,因此我会选择它作为将来来到这里的任何人的适当答案......谢谢! :)
  • 由于 $.when 正在寻找承诺,因此您需要查看的文档部分是:jqXHR.then(function(data, textStatus, jqXHR) {}, function(jqXHR, textStatus, errorThrown) {}); 因此,如果您的所有 ajax 调用都成功,您将获得一个数组数组,每个数组其中有“数据”作为第一项。如果任何 ajax 调用失败,您当前的代码将不会被调用。您将向“then”添加第二个函数,以最后处理“errorThrown”失败的情况。请注意,您总是只会恢复第一次失败(您需要包装 ajax 调用以恢复所有失败)。
猜你喜欢
  • 2016-09-11
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
相关资源
最近更新 更多