Использование jQuery для чтения txt-файла не может вернуть значение из функции

У меня проблема с использованием JQuery для чтения текстового файла и получения значения из функции JQuery get.

Как показано в приведенном ниже коде, первый console.info будет отображать причины правильно, однако, когда он выйдет из функции, во втором журнале консоли ничего не будет.

Интересно, как это исправить?

function getCauses() {
    var causes = new Array();
    if ($("#game-type").val() == "basketball") {

        $.get('basketball.txt', function(data) {
            //split on new lines
            causes = data.split('\n');
            console.info(causes);
        });

        console.info("second: " + causes);
    }

    var c = "<option></option>";
    for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
    }
    return c;
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

$.get() является асинхронным, поэтому вам нужно использовать .then(), если вы хотите, чтобы код запускался после завершения получения.

'$ .get () `возвращает обещание, поэтому у эта страница MDN есть несколько хороших примеров.

Обновлено: я глуп и упустил тот факт, что там уже есть успех. Вы можете попробовать вернуть обещание от $.get() какой-нибудь другой функции и добавить туда все в DOM. В качестве альтернативы, просто делайте вещи DOM напрямую в функции успеха.

Изменить (снова): проблема по-прежнему связана с непониманием того, как работают асинхронные вызовы. Тот факт, что у него есть функция успеха, не меняет ее на неасинхронную, как функция .wait() в C#. Браузер с радостью завершит синхронный вызов $.get(), а затем перейдет к концу функции и вернется, не дожидаясь возврата асинхронной функции. Если OP хочет, чтобы что-то произошло, когда вызов Ajax завершен, либо все должно быть в функции успеха, либо его функция должна возвращать обещание, которое будет использовано в другом месте его кода.

Итак, мое первое предложение будет выглядеть примерно так: оно использует основное обещание и возвращает его для использования позже:

function getCauses() {
  return $.get('basketball.txt');
}

// Use function for stuff
function mainOrWhatever() {
  if ($("#game-type").val() == "basketball") {
    getCauses().done((data)=>{
      var causes = new Array();
      causes = data.split('\n');
      console.info(causes);
      var c = "<option></option>";
      for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
      }
      // Use it for whatever
      $("#dropDown").appendTo(c);
    }
  }
}

Мое второе предложение (и, вероятно, лучшее) - просто поместить все в вызов успеха.

function getCauses() {
  if ($("#game-type").val() == "basketball") {
    $.get('basketball.txt',(data)=>{
      var causes = data.split('\n');
      console.info(causes);
      var c = "<option></option>";
      for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
      }
      // Use it for whatever
      $("#dropDown").appendTo(c);
    });
  }
}

Конечно, всегда можно пойти по пути Бхавика, но я все еще не уверен, что вы хотите задержать загрузку страницы или обработку нажатия кнопки или что-то еще в сетевом вызове, который может занять некоторое время. Похоже, что лучшее решение здесь - это изменить ситуацию, чтобы использовать асинхронный вызов $.get(), а не скрещивать пальцы и надеяться, что ничего не зависнет, пока файл загружен.

OP уже использует функцию обратного вызова, им не обязательно использовать .then()

Phil 22.03.2018 04:58

Большое спасибо за ваше объяснение!

Xin Zhao 23.03.2018 01:56
Ответ принят как подходящий

Все вызовы Ajax могут выполняться либо асинхронно (с функцией обратного вызова, это будет функция, указанная после клавиши «успех»), либо синхронно - эффективно блокируя и ожидая ответа сервера. Чтобы получить синхронное выполнение, вы должны указать

async: false 
function getCauses() {

  var causes = new Array();
  if ($("#game-type").val() == "basketball") {

     $.ajax({
        url:'basketball.txt',
        async: false, // try this
        success:function (data) {
          //split on new lines
          causes = data.split('\n');
          console.info(causes);
        }
     });

     console.info("second: " + causes);
   }

   var c = "<option></option>";
   for (var i = 0; i < causes.length; i++) {
      c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
   }
   return c;
}

Try This

Это был бы другой способ, хотя задержка всего при загрузке файла, вероятно, не лучший вариант, которого можно избежать.

dlkulp 22.03.2018 05:49

Большое спасибо, все работает очень хорошо !!!

Xin Zhao 23.03.2018 01:54

Другие вопросы по теме