有人可以清楚地解释 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() 的工作原理吗?的主要内容,如果未能解决你的问题,请参考以下文章