我有一个简单的网址数组,我想用jQuery加载每个网址。我正在使用$.get
,但是似乎无法使用它$.Deferred
,所以我切换到了$.ajax
-我几乎可以使用它了,但是我得到的结果很奇怪。我希望有人可以帮助我改善这项工作。
var results = [], files = [
'url1', 'url2', 'url3'
];
$.when(
$.ajax(files[0]).done(function(data) {
results.push(data); console.log("step 1.0");
}),
$.ajax(files[1]).done(function(data) {
results.push(data); console.log("step 1.1");
}),
$.ajax(files[2]).done(function(data) {
results.push(data); console.log("step 1.2");
})
).then(function(){
console.log("step 2");
});
这应该输出..
然后results
数组包含所有3个Ajax请求的结果。这可能吗?
首先,您必须决定是要并行处理三个ajax调用(同时运行所有ajax调用,而总运行时间较少),还是依次处理一个ajax调用的运行,完成并启动下一个ajax呼叫。这是一个关键的设计决策,会影响您的执行方式。
使用时,$.when()
您将同时启动所有三个ajax调用。如果仅在所有结果都完成后才检查结果,则仍然可以按特定顺序处理结果(因为只有在所有结果可用时,才可以处理结果,并且将按请求的顺序来处理结果)。但是,以这种方式进行操作时,所有ajax调用都将立即被立即发送。这将为您提供更好的端到端时间,因此,如果这对请求类型可行,则通常是一种更好的方法。
为此,您可以将所需的内容重组为以下形式:
平行运行
var files = [
'url1', 'url2', 'url3'
];
$.when($.ajax(files[0]),$.ajax(files[1]),$.ajax(files[2])).done(function(a1, a2, a3) {
var results = [];
results.push(a1[0]);
results.push(a2[0]);
results.push(a3[0]);
console.log("got all results")
});
因为您一直在等待的.done()
处理程序$.when()
被调用,所以所有的ajax结果都立即准备好了,并$.when()
按照请求的顺序显示(无论哪个先完成),因此您可以尽快获得结果可能,并且它们以可预测的顺序显示。
注意,我还将results
数组的定义移到了$.when()
done处理程序中,因为这是您唯一知道数据实际有效的位置(出于时序原因)。
并行运行-迭代任意长度数组
如果您有一个更长的数组,则可能会发现遍历数组更好,例如以循环方式.map()
处理它们而不是单独列出它们:
var files = [
'url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7'
];
$.when.apply($, files.map(function(url) {
return $.ajax(url);
})).done(function() {
var results = [];
// there will be one argument passed to this callback for each ajax call
// each argument is of this form [data, statusText, jqXHR]
for (var i = 0; i < arguments.length; i++) {
results.push(arguments[i][0]);
}
// all data is now in the results array in order
});
排序Ajax调用
另一方面,如果您实际上要对ajax调用进行排序,以使第二个ajax调用直到第一个完成就不会开始(如果第二个ajax调用需要第一个ajax调用的结果,则可能需要执行某些操作才能知道要求或执行的操作),那么您需要一个完全不同的设计模式,而这$.when()
根本不是可行的方法(它仅执行并行请求)。在这种情况下,您可能只想将结果链接在一起x.then().then()
,然后可以按照您要求的顺序输出日志语句。
$.ajax(files[0]).then(function(data0) {
console.log("step 1.0");
return $.ajax(files[1]);
}).then(function(data1) {
console.log("step 1.1");
return $.ajax(files[2]);
}).done(function(data2) {
console.log("step 1.2");
// all the ajax calls are done here
console.log("step 2");
});
控制台输出:
step 1.0
step 1.1
step 1.2
step 2
如果文件数组较长,也可以将该结构放入循环中,以自动运行N次连续的Ajax调用。尽管您可以在进入results
数组时收集结果,但通常顺序执行操作的原因是先前的结果被下一个ajax调用占用了,因此您通常只需要最终结果。如果您想随时收集结果,则可以results
在每一步将它们推入阵列。
请注意,这里承诺的优势在于,您可以在保持相同的顶层嵌套且不会越来越嵌套的情况下对操作进行排序。
排序Ajax调用-迭代任意长度数组
这是循环中的排序顺序:
var files = [
'url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7'
];
var results = [];
files.reduce(function(prev, cur, index) {
return prev.then(function(data) {
return $.ajax(cur).then(function(data) {
console.log("step 1." + index);
results.push(data);
});
})
}, $().promise()).done(function() {
// last ajax call done
// all results are in the results array
console.log("step 2.0");
});
控制台输出:
step 1.0
step 1.1
step 1.2
step 1.3
step 1.4
step 1.5
step 1.6
step 2
该Array.prototype.reduce()
方法在这里很容易使用,因为在处理每个单独的数组元素时它会累积一个值,这是在.then()
为每个数组元素添加时需要执行的操作。该.reduce()
迭代开始与空/解决承诺$().promise()
(也有其他的方式来还可以创建这样的承诺),它只是给我们的东西,开始做.then()
对已经解决。
问题内容: 您能否举一个使用jquery读取jsonp请求的非常简单的示例?我就是无法正常工作。 问题答案: 这是工作示例: 注意所请求URL的末尾。这表明我们要使用JSONP。删除它,将使用原始的JSON请求。由于相同的原产地政策而失败。 您可以在JQuery网站上找到更多信息和示例:http : //api.jquery.com/jQuery.getJSON/
问题内容: 我不太了解如何使用jQuery的ajax函数的回调。 我在JavaScript中有以下代码: 在服务器端(AppEngine / Python),我获取了回调参数的值并使用 但是随后我在浏览器控制台中看到了。 处理此问题的正确方法是什么?现在,我得到了所需的结果,但是我知道这不正确的事实困扰着我。 问题答案: 这就是我在我身上所做的
我已经成功地将我的索引页面转换成pdf格式,遵循来自互联网的文档,但是我不能使用带有参数的URL,如下所示 它返回错误,如何从这个url转换为PDF
问题内容: 我试图使用ES6 Promise通过jQuery发出发布请求: 我有一个功能: 我这样称呼它: 我的服务器正在返回预期的响应,请求主体为JSON格式,但我的控制台输出为: 好:未定义 为什么我没有得到返回的数据? 感谢任何人/所有人的帮助。 -更新编辑- 我已将我的js减少为: 我仍然未定义为输出。如果在“网络”选项卡中打开请求,则可以看到带有正确数据的响应对象。发出了请求,我的服务器
问题内容: 我使用Vlad Mihalcea的库来将SQL数组(在我的情况下为Postgresql)映射到JPA。然后,假设我有一个实体,例如。 适当的SQL是: 使用QueryDSL,我想获取包含所有给定标签的行。原始SQL可能是: (摘自:https : //www.postgresql.org/docs/9.1/static/functions- array.html ) 可以用QueryD
在我开发的一个应用程序上,我试图为应用程序的页面保留一个好的、可读的url。我从url开始,如下所示:http://somedomain.com/context/?param1=value getRequestCycle()。setResponsePage(新建其他页面(obj1、obj2、pageParameters) 在这里,目标1和目标2是初始化页面所需的对象。正如我从这篇文章中理解的那样,