I'm attempting to loop through an ajax call for 3 different json files with the same naming convention and structure (but with slightly different data). I have been using deferred objects instead of the success option ever since I read a response by Alnitak in the forum (jQuery ajax success callback function definition) so that my ajax handling and callback handling could be decoupled. Below is my code:
我正在尝试循环使用具有相同命名约定和结构的3个不同json文件的ajax调用(但数据略有不同)。自从我在论坛中阅读Alnitak的回复(jQuery ajax成功回调函数定义)以来,我一直在使用延迟对象而不是成功选项,这样我的ajax处理和回调处理就可以解耦了。以下是我的代码:
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1" />
<title>Stuff</title>
<script src="jquery-1.9.1.min.js" type="text/javascript"></script>
</head>
<body>
<script Language="JavaScript">
var myData = [];
var myURL = ["ticker1.json","ticker2.json","ticker3.json"]; //New Array for my URLs
function getData(m) {
return $.ajax({
url : myURL[m], //<<<---Want to loop through this array
type : 'GET',
dataType: 'json'
});
}
function handleData(data){
for (var i=0; i<data.test.msgOne.length; i++){
myData[i] = data.test.msgOne[i];
}
};
for (var j=0; j<3; j++){
console.log(j); //<<---First console statement
var ajaxCall = getData(j).done(handleData);
$.when(ajaxCall).done(function(){ //wait until the ajax call is done before writing
console.log(j); //<<---Second console statement
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
});
}
</script>
</body>
</html>
My code consists of an function called getData which performs an ajax call, then a function called handleData which simply loops through data in the json file from the ajax call and stores the data in an array myData. Then a for-loop attempts to output the data for the array myData to the screen. However, the problem is I am only getting the data from the first json file output on the screen, instead of all three sequentially.
我的代码包含一个名为getData的函数,它执行ajax调用,然后是一个名为handleData的函数,它只是从ajax调用中循环遍历json文件中的数据,并将数据存储在数组myData中。然后for循环尝试将数组myData的数据输出到屏幕。但是,问题是我只是从屏幕上的第一个json文件输出获取数据,而不是所有三个顺序。
So what I did was input two console.log statements in the for-loop: one before the ajax call and one after the ajax call gets done. The first console.log outputs 0,1,2 sequentially as expected, and the second gives a 3, which is unexpected. So then I assumed that the ajax calls weren't returning before the counter finishes. I replaced the for-loop with some logic statements and a while-loop (yes, I know the dangers of code running indefinitely) given below:
所以我所做的是在for循环中输入两个console.log语句:一个在ajax调用之前,一个在ajax调用完成之后。第一个console.log按预期顺序输出0,1,2,第二个给出3,这是意外的。所以我假设在计数器完成之前ajax调用没有返回。我用一些逻辑语句和一个while循环替换了for循环(是的,我知道无限期运行代码的危险),如下所示:
var j=0;
var whileFlag= new Boolean(1);
var ajaxFlag = new Boolean(1);
while (whileFlag) {
if (ajaxFlag > 0) {
ajaxFlag = 0;
console.log(j);
var ajaxCall = getData(j).done(handleData);
}
$.when(ajaxCall).done(function(){
console.log(j);
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
ajaxFlag = 1;
j++;
});
if (j>=3) {whileFlag = 0};
}
The replacement code was an attempt to force the ajax calls to finish and then execute code before moving onto the next ajax call. Well, the end result was a frozen browser, which was no bueno. Does anyone know how I might be able to go about writing the myData array for each of my json files to the screen? Any help and constructive comments are appreciated. Also, I need to keep the ajax call asynchronous since I will be working with jsonp datatypes in the future.
替换代码试图强制ajax调用完成然后执行代码,然后再转到下一个ajax调用。好吧,最终结果是一个冻结的浏览器,这是没有bueno。有谁知道我怎样才能将每个json文件的myData数组写入屏幕?任何帮助和建设性意见表示赞赏。此外,我需要保持ajax调用异步,因为我将来会使用jsonp数据类型。
Additional question: I believe the browser hang up is due to ajax not returning the call, but the questions is why? If I choose not to implement the for-loop in the first example, and instead just set the j variable explicitly to 0, or 1, or 2, the data prints-out fine for the chosen json file, but If I do more than that it will only print the set of data from the first json file. It's like it's not possible to do multiple ajax calls or something. Any insight and help is appreciated. Thanks.
附加问题:我认为浏览器挂机是由于ajax没有回复电话,但问题是为什么?如果我选择不在第一个示例中实现for循环,而只是将j变量显式设置为0,或1或2,则数据打印输出正好用于所选的json文件,但是如果我做的多于它只会打印第一个json文件中的数据集。这就像是不可能做多个ajax调用或其他东西。任何见解和帮助表示赞赏。谢谢。
3 个解决方案
#1
2
The problem is your while loop is equivalent to...
问题是你的while循环相当于......
while (whileFlag) {
if (ajaxFlag > 0) {
ajaxFlag = 0;
console.log(j);
var ajaxCall = getData(j).done(handleData);
}
// Some thrid party (asynch Handler) changes j
if (j>=3) {whileFlag = 0};
}
so ideally till Ajax completes your code runs as
理想情况下,直到Ajax完成您的代码运行为
while (whileFlag) {
if (j>=3) {whileFlag = 0};
}
which hangs your browser...
它挂起你的浏览器......
If you want to really wait for 2nd Ajax call till 1st completes and so on..
如果你真的要等到第二次Ajax通话,直到第一次完成,依此类推......
function getData(m) {
return $.ajax({
url : myURL[m], //<<<---Want to loop through this array
type : 'GET',
dataType: 'json',
myJ: m
});
}
function handleData(data){
for (var i=0; i<data.test.msgOne.length; i++){
myData[i] = data.test.msgOne[i];
}
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
if(this.myJ<2){
var myJ=this.myJ;
setTimeout(function(){
getData((myJ+1)).done(handleData).fail(failed);
}, 100);
}
};
getData(0).done(handleData);
function failed(jqXHR, textStatus, errorThrown){
alert("textStatus="+textStatus);
alert("Error= "+errorThrown);
}
As per comment with alert if its working then use settimeout.. and it will work
根据警告的评论如果它的工作然后使用settimeout ..它将工作
#2
0
Here are the three json files in case you want to test things yourself:
以下是三个json文件,以防您想自己测试:
-
ticker1.json:
ticker1.json:
{ "test": { "msgOne": [ "ticker1 Remote One", "ticker1 Remote Two", "ticker1 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker1 Remote One”,“ticker1 Remote Two”,“ticker1 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
-
ticker2.json:
ticker2.json:
{ "test": { "msgOne": [ "ticker2 Remote One", "ticker2 Remote Two", "ticker2 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker2 Remote One”,“ticker2 Remote Two”,“ticker2 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
-
ticker3.json:
ticker3.json:
{ "test": { "msgOne": [ "ticker3 Remote One", "ticker3 Remote Two", "ticker3 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker3 Remote One”,“ticker3 Remote Two”,“ticker3 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
#3
0
If you know there are always three calls, you could do something like this:
如果您知道总有三个电话,您可以这样做:
function getData(url) {
return $.ajax({
url: url,
//...
});
}
function handleData(data1, data2, data3) {
//display the data however you like
}
$(document).ready(function() {
var request1 = getData(myUrl[0]);
var request2 = getData(myUrl[1]);
var request3 = getData(myUrl[2]);
$.when(request1, request2, request3)
.done(function(result1, result2, result3) {
alert(result1.test.msgOne[0]);
});
});
In this case, handleData()
will only be called once, after all three calls have finished.
在这种情况下,只有在完成所有三个调用之后,handleData()才会被调用一次。
If you don't know how many results you'll have, you could iterate over the myUrl array and push the deferred
s into an array. try this link for an example of passing an array of deferred
objects to $.when()
.
如果您不知道自己将获得多少结果,则可以迭代myUrl数组并将延迟数据推送到数组中。尝试此链接以获取将延迟对象数组传递给$ .when()的示例。
Another edit
另一个编辑
I've updated the original code. I think you're getting hung up on the deferred object. The deferred object (request1
, for example) does not contain the response. When you call $.when(request1).done(function(result1) { });
the json result of request1 is passed into the function.
我已经更新了原始代码。我想你已经挂断了延迟对象。延迟对象(例如,request1)不包含响应。当你调用$ .when(request1).done(function(result1){}); request1的json结果传递给函数。
#1
2
The problem is your while loop is equivalent to...
问题是你的while循环相当于......
while (whileFlag) {
if (ajaxFlag > 0) {
ajaxFlag = 0;
console.log(j);
var ajaxCall = getData(j).done(handleData);
}
// Some thrid party (asynch Handler) changes j
if (j>=3) {whileFlag = 0};
}
so ideally till Ajax completes your code runs as
理想情况下,直到Ajax完成您的代码运行为
while (whileFlag) {
if (j>=3) {whileFlag = 0};
}
which hangs your browser...
它挂起你的浏览器......
If you want to really wait for 2nd Ajax call till 1st completes and so on..
如果你真的要等到第二次Ajax通话,直到第一次完成,依此类推......
function getData(m) {
return $.ajax({
url : myURL[m], //<<<---Want to loop through this array
type : 'GET',
dataType: 'json',
myJ: m
});
}
function handleData(data){
for (var i=0; i<data.test.msgOne.length; i++){
myData[i] = data.test.msgOne[i];
}
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
if(this.myJ<2){
var myJ=this.myJ;
setTimeout(function(){
getData((myJ+1)).done(handleData).fail(failed);
}, 100);
}
};
getData(0).done(handleData);
function failed(jqXHR, textStatus, errorThrown){
alert("textStatus="+textStatus);
alert("Error= "+errorThrown);
}
As per comment with alert if its working then use settimeout.. and it will work
根据警告的评论如果它的工作然后使用settimeout ..它将工作
#2
0
Here are the three json files in case you want to test things yourself:
以下是三个json文件,以防您想自己测试:
-
ticker1.json:
ticker1.json:
{ "test": { "msgOne": [ "ticker1 Remote One", "ticker1 Remote Two", "ticker1 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker1 Remote One”,“ticker1 Remote Two”,“ticker1 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
-
ticker2.json:
ticker2.json:
{ "test": { "msgOne": [ "ticker2 Remote One", "ticker2 Remote Two", "ticker2 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker2 Remote One”,“ticker2 Remote Two”,“ticker2 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
-
ticker3.json:
ticker3.json:
{ "test": { "msgOne": [ "ticker3 Remote One", "ticker3 Remote Two", "ticker3 Remote Three" ], "msgTwo": "Remote2", "msgThree": "Remote3" } }
{“test”:{“msgOne”:[“ticker3 Remote One”,“ticker3 Remote Two”,“ticker3 Remote Three”],“msgTwo”:“Remote2”,“msgThree”:“Remote3”}}
#3
0
If you know there are always three calls, you could do something like this:
如果您知道总有三个电话,您可以这样做:
function getData(url) {
return $.ajax({
url: url,
//...
});
}
function handleData(data1, data2, data3) {
//display the data however you like
}
$(document).ready(function() {
var request1 = getData(myUrl[0]);
var request2 = getData(myUrl[1]);
var request3 = getData(myUrl[2]);
$.when(request1, request2, request3)
.done(function(result1, result2, result3) {
alert(result1.test.msgOne[0]);
});
});
In this case, handleData()
will only be called once, after all three calls have finished.
在这种情况下,只有在完成所有三个调用之后,handleData()才会被调用一次。
If you don't know how many results you'll have, you could iterate over the myUrl array and push the deferred
s into an array. try this link for an example of passing an array of deferred
objects to $.when()
.
如果您不知道自己将获得多少结果,则可以迭代myUrl数组并将延迟数据推送到数组中。尝试此链接以获取将延迟对象数组传递给$ .when()的示例。
Another edit
另一个编辑
I've updated the original code. I think you're getting hung up on the deferred object. The deferred object (request1
, for example) does not contain the response. When you call $.when(request1).done(function(result1) { });
the json result of request1 is passed into the function.
我已经更新了原始代码。我想你已经挂断了延迟对象。延迟对象(例如,request1)不包含响应。当你调用$ .when(request1).done(function(result1){}); request1的json结果传递给函数。