有人可以清楚地解释 jQuery.when() 和 deferred.then() 的工作原理吗?

Posted

技术标签:

【中文标题】有人可以清楚地解释 jQuery.when() 和 deferred.then() 的工作原理吗?【英文标题】:Can someone explain clearly how jQuery.when() and deferred.then() works? 【发布时间】: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 数据... 【参考方案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 调用以恢复所有失败)。

以上是关于有人可以清楚地解释 jQuery.when() 和 deferred.then() 的工作原理吗?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery异步框架探究3:jQuery.when方法

jQuery异步框架探究3:jQuery.when方法

有人可以解释 HTML5 aria-* 属性吗?

有人可以为我非常简单地解释 MVC 吗? [复制]

我不明白注入依赖是如何工作的。有没有人可以清楚地解释我

有人可以简单地向我解释啥是有向无环图吗?