CSV в массив — проблема с jquery и ajax

#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);
    }
  );
};