我正在尝试存储像这样返回的JSON对象
<div id="tabs-1" class="LIVE"></div>
<div id="tabs-2" class="past-matches"></div>
<div id="tabs-3" class="upcoming-matches"></div>
使用以下脚本。
$(function() {
query=["select * from cricket.scorecard.live.summary","select * from cricket.past_matches", "select * from cricket.upcoming_matches"]
container=[".LIVE",".past-matches",".upcoming-matches"]
container_no=0
query_no=0;
for( var section=0;section<query.length;section++)
{
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
jsonp: "callback",
dataType: "jsonp",
data: {
q: query[query_no++],
env:"store://0TxIGQMQbObzvU4Apia0V0",
format: "json"
},
// Work with the response
success: function(data ) {
console.log( data ); // The problem: returns JSON objects in different order everytime the page reloads
//I would like to store data like this
if(container_no>0)
{
if(container_no==1)
{ $(container[container_no]).append('<p>recent match data</p>');
container_no++;
}
else
{
$(container[container_no]).append('<p>upcoming match data</p>');
container_no++;
}
}
else{
$(container[container_no]).append('<p>live match data</p>');
container_no++;
}
}
});
}
});
问题是每次重新加载页面时JSON对象都以不同的顺序返回,所以我无法将数据保存在正确的div中。我想我做了一个涉及变量范围的错误。 这是小提琴:FIDDLE
答案 0 :(得分:2)
Ajax调用是异步的(&#34; A&#34;代表Ajax)。因此,它们具有不确定的执行时间,并且当您执行多个Ajax调用时,没有保证结果将到达的顺序。
因此,如果你想知道哪个结果是哪个(例如哪个是第一个,第二个等等),你必须创建一个对每个ajax调用都是唯一的计数器。一种方法是将每个Ajax调用放入函数调用并将计数器传递给该函数调用。此函数将创建一个闭包,当结果返回时,将为您维护计数器。
这是一个使用函数的版本,该函数来自使用.forEach()
来迭代查询数组。我还做了一些其他修改来简化代码:
$(function() {
var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"];
var container = [".LIVE", ".past-matches", ".upcoming-matches"];
var msg = ['<p>live match data</p>', '<p>recent match data</p>', '<p>upcoming match data</p>'];
query.forEach(function(queryVal, cnt) {
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
jsonp: "callback",
dataType: "jsonp",
data: {
q: queryVal,
env: "store://0TxIGQMQbObzvU4Apia0V0",
format: "json"
},
// Work with the response
success: function(data) {
console.log(data);
$(container[cnt]).append(msg[cnt]);
}
});
}
});
这是另一个创建IIFE(立即调用的函数表达式)来解决同样问题的版本:
$(function() {
var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"];
var container = [".LIVE", ".past-matches", ".upcoming-matches"];
for (var section = 0; section < query.length; section++) {
// add IIFE so we can capture the section number uniquely for each ajax call
(function(cnt) {
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
jsonp: "callback",
dataType: "jsonp",
data: {
q: query[cnt],
env: "store://0TxIGQMQbObzvU4Apia0V0",
format: "json"
},
// Work with the response
success: function(data) {
console.log(data);
var msg;
if (cnt === 0) {
msg = '<p>live match data</p>'
} else if (cnt === 1) {
msg = '<p>recent match data</p>';
} else {
msg = '<p>upcoming match data</p>';
}
$(container[cnt]).append(msg);
}
});
})(section);
}
});
注意,我还在所有局部变量中添加了var
,因此您不会意外地创建全局变量。
如果你真的想等到收集到所有结果,那么你可以完全按照循环顺序添加它们,那么你可以使用jQuery&#39; $.when()
来做到这一点。
$(function() {
var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"];
var container = [".LIVE", ".past-matches", ".upcoming-matches"];
var msg = ['<p>live match data</p>', '<p>recent match data</p>', '<p>upcoming match data</p>'];
var promises = [];
query.forEach(function(queryVal, cnt) {
promises.push($.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
jsonp: "callback",
dataType: "jsonp",
data: {
q: queryVal,
env: "store://0TxIGQMQbObzvU4Apia0V0",
format: "json"
},
}));
}
// wait for all ajax results to be done
$.when.apply($, promises).then(function() {
for (var i = 0; i < arguments.length; i++) {
// iterate all results in order
console.log(arguments[i][0]);
}
});
});