我需要从服务器上的一系列.csv文件中提取数据。我正在将csvs转换为数组,我试图将它们全部保存在一个对象中。 ajax请求都是成功的,但由于某种原因,只有来自最后一个请求的数据才会在对象中结束。这是我的代码:
var populate_chart_data = function(){
"use strict";
var genders = ["Boys","Girls"];
var charts = {
WHO: ["HCFA", "IWFA", "LFA", "WFA", "WFL"],
CDC: ["BMIAGE", "HCA", "IWFA", "LFA", "SFA", "WFA", "WFL", "WFS"]
};
var fileName, fileString;
var chart_data = {};
for (var i=0; i < genders.length; i++){
for (var item in charts){
if (charts.hasOwnProperty(item)){
for (var j=0; j<charts[item].length; j++) {
fileName = genders[i] + '_' + item + '_' + charts[item][j];
fileString = pathString + fileName + '.csv';
$.ajax(fileString, {
success: function(data) {
chart_data[fileName] = csvToArray(data);
},
error: function() {
console.log("Failed to retrieve csv");
},
timeout: 300000
});
}
}
}
}
return chart_data;
};
var chart_data = populate_chart_data();
Firebug中的控制台显示每个ajax请求成功,但是当我逐步执行循环时,我的chart_data对象为空,直到最后一个循环。这是我第一次涉足ajax。这是时间问题吗?
答案 0 :(得分:2)
这里有两件事需要考虑:
AJAX调用是异步的,这意味着只有在收到数据后才会调用回调。与此同时,你的循环继续前进并排队新的请求。
由于您正在进行循环,因此filename
的值将在执行回调之前发生变化。
所以你需要做两件事:
var chart_data = [];
var requests = [];
for (var j=0; j<charts[item].length; j++) {
fileName = genders[i] + '_' + item + '_' + charts[item][j];
fileString = pathString + fileName + '.csv';
var onSuccess = (function(filenameinclosure){ // closure for your filename
return function(data){
chart_data[filenameinclosure] = csvToArray(data);
};
})(fileName);
requests.push( // saving requests
$.ajax(fileString, {
success: onSuccess,
error: function() {
console.log("Failed to retrieve csv");
},
timeout: 300000
})
);
}
$.when.apply(undefined, requests).done(function () {
// chart_data is filled up
});
答案 1 :(得分:1)
我很惊讶任何数据都会在对象中结束。关于ajax的事情是,你不能依赖于知道请求何时完成(或者甚至是否完成)。因此,任何依赖于检索的data
的工作都必须在ajax回调中完成。你可以这样:
var requests = [];
var chart_data = {};
/* snip */
requests.push($.ajax(fileString, {
/* snip */
$.when.apply(undefined, requests).done(function () {
//chart_data should be full
});