Javascript/jQuery 中的并行 Ajax 调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12429765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parallel Ajax Calls in Javascript/jQuery
提问by Raghuveer
I am completely new to Javascript/jquery world and need some help. Right now, I am writing one html page where I have to make 5 different Ajax calls to get the data to plot graphs. Right now, I am calling these 5 ajax calls like this:
我对 Javascript/jquery 世界完全陌生,需要一些帮助。现在,我正在编写一个 html 页面,我必须在其中进行 5 次不同的 Ajax 调用来获取数据以绘制图形。现在,我像这样调用这 5 个 ajax 调用:
$(document).ready(function() {
area0Obj = $.parseJSON($.ajax({
url : url0,
async : false,
dataType : 'json'
}).responseText);
area1Obj = $.parseJSON($.ajax({
url : url1,
async : false,
dataType : 'json'
}).responseText);
.
.
.
area4Obj = $.parseJSON($.ajax({
url : url4,
async : false,
dataType : 'json'
}).responseText);
// some code for generating graphs
)} // closing the document ready function
My problem is that in above scenario, all the ajax calls are going serially. That is, after 1 call is complete 2 starts, when 2 completes 3 starts and so on .. Each Ajax call is taking roughly around 5 - 6 sec to get the data, which makes the over all page to be loaded in around 30 sec.
我的问题是,在上面的场景中,所有的 ajax 调用都是串行进行的。也就是说,1 次调用完成后 2 次启动,当 2 次完成时 3 次启动等等.. 每个 Ajax 调用大约需要 5 - 6 秒才能获取数据,这使得整个页面在大约 30 秒内加载.
I tried making the async type as true but in that case I dont get the data immediately to plot the graph which defeats my purpose.
我尝试将 async 类型设为 true,但在这种情况下,我不会立即获取数据来绘制违背我目的的图表。
My question is: How can I make these calls parallel, so that I start getting all this data parallely and my page could be loaded in less time?
我的问题是:如何使这些调用并行,以便我开始并行获取所有这些数据,并且可以在更短的时间内加载我的页面?
Thanks in advance.
提前致谢。
回答by gbs
Using jQuery.when(deferreds):
使用jQuery.when(延迟):
$.when( $.ajax("/req1"), $.ajax("/req2"), $.ajax("/req3") ).then(function(resp1, resp2, resp3){
// plot graph using data from resp1, resp2 & resp3
});
callback function only called when all 3 ajax calls are completed.
回调函数仅在所有 3 个 ajax 调用完成时调用。
回答by Abraham
You can't do that using async: false
- the code executes synchronously, as you already know (i.e. an operation won't start until the previous one has finished).
You will want to set async: true
(or just omit it - by default it's true). Then define a callback function for each AJAX call. Inside each callback, add the received data to an array. Then, check whether all the data has been loaded (arrayOfJsonObjects.length == 5
). If it has, call a function to do whatever you want with the data.
您不能使用async: false
- 代码同步执行,正如您已经知道的(即,在前一个操作完成之前,操作不会开始)。
你会想要设置async: true
(或只是省略它 - 默认情况下它是真的)。然后为每个 AJAX 调用定义一个回调函数。在每个回调中,将接收到的数据添加到数组中。然后,检查是否已加载所有数据(arrayOfJsonObjects.length == 5
)。如果有,调用一个函数来对数据做任何你想做的事情。
回答by xiaose
Let's try to do it in this way:
让我们尝试这样做:
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var area0Obj = {responseText:''};
var area1Obj = {responseText:''};
var area2Obj = {responseText:''};
var url0 = 'http://someurl/url0/';
var url1 = 'http://someurl/url1/';
var url2 = 'http://someurl/url2/';
var getData = function(someURL, place) {
$.ajax({
type : 'POST',
dataType : 'json',
url : someURL,
success : function(data) {
place.responseText = data;
console.log(place);
}
});
}
getData(url0, area0Obj);
getData(url1, area1Obj);
getData(url2, area2Obj);
});
</script>
if server side will be smth. like this:
如果服务器端将是 smth。像这样:
public function url0() {
$answer = array(
array('smth' => 1, 'ope' => 'one'),
array('smth' => 8, 'ope' => 'two'),
array('smth' => 5, 'ope' => 'three')
);
die(json_encode($answer));
}
public function url1() {
$answer = array('one','two','three');
die(json_encode($answer));
}
public function url2() {
$answer = 'one ,two, three';
die(json_encode($answer));
}
So there, as you can see, created one function getData() for getting data from server and than it called 3 times. Results will be received in asynchronous way so, for example, first can get answer for third call and last for first call.
因此,如您所见,创建了一个函数 getData() 用于从服务器获取数据,然后调用了 3 次。结果将以异步方式接收,例如,第一个可以得到第三个调用的答案,最后一个调用。
Console answer will be:
控制台答案将是:
[{"smth":1,"ope":"one"},{"smth":8,"ope":"two"},{"smth":5,"ope":"three"}]
["one","two","three"]
"one ,two, three"
PS. please read this: http://api.jquery.com/jQuery.ajax/there you can clearly see info about async. There default async param value = true.
附注。请阅读:http: //api.jquery.com/jQuery.ajax/在那里您可以清楚地看到有关异步的信息。有默认的异步参数值 = true。
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active...
默认情况下,所有请求都是异步发送的(即默认设置为 true)。如果您需要同步请求,请将此选项设置为 false。跨域请求和 dataType: "jsonp" 请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作...
回答by Teena Thomas
you may combine all the functionality of the different ajax functions into 1 ajax function, or from 1 ajax function, call the other functions (they would be private/controller side in this case) and then return the result. Ajax calls do stall a bit, so minimizing them is the way to go.
您可以将不同 ajax 函数的所有功能组合到 1 个 ajax 函数中,或者从 1 个 ajax 函数调用其他函数(在这种情况下它们将是私有/控制器端),然后返回结果。Ajax 调用确实有点停滞,所以尽量减少它们是可行的方法。
you can also make the ajax functions asynchronous (which then would behave like normal functions), then you can render the graph at the end, after all the functions return their data.
您还可以使 ajax 函数异步(然后它会像普通函数一样运行),然后您可以在最后呈现图形,在所有函数返回它们的数据之后。
回答by lucassp
Here's a solution to your issue: http://jsfiddle.net/YZuD9/
这是您问题的解决方案:http: //jsfiddle.net/YZuD9/
回答by Nelles
The following worked for me - I had multiple ajax calls with the need to pass a serialised object:
以下对我有用 - 我有多个 ajax 调用需要传递序列化对象:
var args1 = {
"table": "users",
"order": " ORDER BY id DESC ",
"local_domain":""
}
var args2 = {
"table": "parts",
"order": " ORDER BY date DESC ",
"local_domain":""
}
$.when(
$.ajax({
url: args1.local_domain + '/my/restful',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(args1),
error: function(err1) {
alert('(Call 1)An error just happened...' + JSON.stringify(err1));
}
}),
$.ajax({
url: args2.local_domain + '/my/restful',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(args2),
error: function(err2) {
calert('(Call 2)An error just happened...' + JSON.stringify(err2));
}
})
).then(function( data1, data2 ) {
data1 = cleanDataString(data1);
data2 = cleanDataString(data2);
data1.forEach(function(e){
console.log("ids" + e.id)
});
data2.forEach(function(e){
console.log("dates" + e.date)
});
})
function cleanDataString(data){
data = decodeURIComponent(data);
// next if statement was only used because I got additional object on the back of my JSON object
// parsed it out while serialised and then added back closing 2 brackets
if(data !== undefined && data.toString().includes('}],success,')){
temp = data.toString().split('}],success,');
data = temp[0] + '}]';
}
data = JSON.parse(data);
return data; // return parsed object
}
回答by dkleehammer
You won't be able to handle it like your example. Setting to async uses another thread to make the request on and lets your application continue.
你将无法像你的例子那样处理它。设置为 async 使用另一个线程来发出请求并让您的应用程序继续。
In this case you should utilize a new function that will plot an area out, then use the callback functions of the ajax request to pass the data to that function.
在这种情况下,您应该使用一个新函数来绘制一个区域,然后使用 ajax 请求的回调函数将数据传递给该函数。
For example:
例如:
$(document).ready(function() {
function plotArea(data, status, jqXHR) {
// access the graph object and apply the data.
var area_data = $.parseJSON(data);
}
$.ajax({
url : url0,
async : false,
dataType : 'json',
success: poltArea
});
$.ajax({
url : url1,
async : false,
dataType : 'json',
success: poltArea
});
$.ajax({
url : url4,
async : false,
dataType : 'json',
success: poltArea
});
// some code for generating graphs
}); // closing the document ready function
回答by Pedro Cordeiro
It looks like you need to dispatch your request asynchronously and define a callback function to get the response.
看起来您需要异步调度您的请求并定义一个回调函数来获取响应。
The way you did, it'll wait until the variable is successfully assigned (meaning: the response has just arrived) until it proceeds to dispatch the next request. Just use something like this.
按照你的方式,它会一直等到变量被成功分配(意思是:响应刚刚到达),直到它继续发送下一个请求。只需使用这样的东西。
$.ajax({
url: url,
dataType: 'json',
data: data,
success: function(data) {
area0Obj = data;
}
});
This should do the trick.
这应该可以解决问题。