#jquery #ajax #csv
#jquery #ajax #csv
Вопрос:
Я пытаюсь реализовать функцию, которая загружала бы сохраненный на сервере CSV-файл и преобразовывала его в массив. У меня есть некоторые проблемы с этим, и я был бы благодарен за помощь.
Вот как функция выглядит на данный момент:
function getSeries(filename){
//create an array where objects will be stored.
var seriesInFile=[];
$.get('/public/csv/' filename '.csv',
function(data) {
// Split the lines
var lines = data.split('n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
//elements from each line are taken and stored
series = {
//some other attributes here, I took them off for this example
data: []
}
$.each(items, function(itemNo, item) {
series.data.push(parseFloat(item));
});
seriesInFile.push(series);
});
console.log(seriesInFile); //it works here!
});
return seriesInFile;
};
console.log(getSeries('hr'));
console.log(getSeries('hr'));
Итак, проблема в том, что, хотя я успешно получаю информацию из файла CSV и сохраняю ее в ‘seriesInFile’ внутри функции $.each, как только я выхожу из нее, она больше не работает — вся функция возвращает пустой массив.
Я предполагаю, что это может быть как-то связано с тем, что функция get () была развернута немного позже, чем исходная функция getSeries. Есть ли простое решение для этого?
Спасибо,
Комментарии:
1. Почему бы вам не выполнить обработку на стороне сервера и не использовать json для ее передачи?
Ответ №1:
Я думаю, вы должны вернуть seriesInFile из функции обратного вызова $.GET
function getSeries(filename){
//create an array where objects will be stored.
var seriesInFile=[];
$.get('/public/csv/' filename '.csv',
function(data) {
// Split the lines
var lines = data.split('n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
//elements from each line are taken and stored
series = {
//some other attributes here, I took them off for this example
data: []
}
$.each(items, function(itemNo, item) {
series.data.push(parseFloat(item));
});
seriesInFile.push(series);
});
console.log(seriesInFile); //it works here!
// do what you need to do with seriesInfile here
//like calling a function to display it
});
//here seriesInFile is an empty array;
};
Поскольку $.GET выполняет асинхронный вызов к серверу, выполняется весь остальной код: в вашем примере вы возвращаете seriesInFile как пустой массив, потому что ваша функция не ожидает завершения вызова AJAX и просто возвращает seriesInFile, как вы его объявили.
Если вы хотите вернуть его, вы должны сделать это в функции обратного вызова $.GET, которая выполняется при успешном выполнении AJAX-вызова.
РЕДАКТИРОВАТЬ — Как предложено в комментарии, возврат из обратного вызова, вероятно, не работает (никогда не пробовал). Обычно вы должны делать все, что вам нужно, непосредственно из функции обратного вызова (это то, что я обычно делаю). Если вам нужна помощь с чем-то конкретным, я могу помочь
Комментарии:
1. Ваш анализ верен: запрос GET является асинхронным и завершается спустя долгое время после возврата функции
getSeries
. Однако я не думаю, что ваш код полезен. Простой возврат массива из обратного вызова не будет иметь никакого значения.
Ответ №2:
Как правильно указала Никола Пелучетти, запрос GET является асинхронным. Это означает, что он запускается при вызове $.get
, но если заканчивается позже. Функция getSeries
немедленно возвращается. На данный момент массив все еще пуст, поскольку запрос GET не завершен.
Что бы вы ни хотели сделать с проанализированными CSV-данными, вы должны инициировать это из обратного вызова запроса GET, а не из вызвавшей его функции getSeries
(которую лучше было бы вызвать startSeriesRetrieval
).
Таким образом, это может выглядеть следующим образом ( displaySeries
вызывается для дальнейшей работы с полученными данными):
function startSeriesRetrieval(filename) {
$.get('/public/csv/' filename '.csv',
function(data) {
// Split the lines
var lines = data.split('n');
var seriesInFile=[];
$.each(lines, function(lineNo, line) {
var items = line.split(',');
//elements from each line are taken and stored
series = {
//some other attributes here, I took them off for this example
data: []
}
$.each(items, function(itemNo, item) {
series.data.push(parseFloat(item));
});
seriesInFile.push(series);
});
displaySeries(seriesInFile);
}
);
};