функция JavaScript возвращаемое значение путаница - PullRequest
4 голосов
/ 13 июня 2011

Мне неясно, какое значение возвращает следующий фиктивный код:

function foo()
  var ret = 0;
  var xhr=send_request( "bla", function() {
      // do something with the AJAX response
      // based on the value of response, var ret get set
  } );
  return ret;
}

Чего я хотел бы добиться, так это: основываясь на ответе AJAX, я мог бы решить повторить запрос. Но указанная выше функция всегда возвращает 0 независимо.

Очевидно, я могу сделать так, чтобы функция foo () решила вызвать send_request () дважды, когда это необходимо, но это немного уродливо. Есть ли простой и приятный способ сделать это?

Спасибо

Ответы [ 4 ]

7 голосов
/ 13 июня 2011

Вы пытаетесь сделать вызов ajax синхронно, но вы делаете асинхронный вызов.

Важно понимать, что, как вы его написали, код не ожидает завершения вызова AJAX, прежде чем перейти к следующей строке. Поэтому он всегда возвращает начальное значение ret.

Сделайте несколько вещей, чтобы исправить это:

  • Используйте jQuery (если вы еще этого не сделали)
  • Используйте функцию jQuery ajax () и установите для async значение false.

Должно выглядеть примерно так:

function foo()
    var ret = $.ajax({ url: "blah",
                       async: false
                     }).responseText;

    // do your stuff here

    return ret;
}

РЕДАКТИРОВАТЬ: Это можно сделать с помощью асинхронного вызова, но вы должны настроить способ, которым вы думаете о проблеме. Вместо того, чтобы думать о возвращаемых значениях, вы должны думать о функциях обратного вызова.

Для примера, скажем, я пытаюсь получить имя пользователя и разместить его на странице. Мой код будет выглядеть примерно так:

function GetUsername() {
    $.ajax( { url: "blah",
              success: PopulateUsername    // Specify a callback
            });
    // I don't do anything else. Execution will continue when the
    // callback gets called from the AJAX call.
}

function PopulateUsername(data) {
    alert(data);
    // Anything else I want to do, I do here, because it is only 
    // here that I have access to the result.
}

GetUsername();  // I call GetUsername() here, and that's it. Any
                // further actions that need to happen are going to
                // occur in the callback function
0 голосов
/ 13 июня 2011

Вы не хотите возвращать значение из функции, которая собирается выполнить вызов AJAX, потому что запрос AJAX не будет выполнен до того, как функция вернется (и лично я не согласен с ответами, которые говорят, что вы должны установить async в ложный). Вы хотите сделать что-то вроде этого:

function retFunction(val) {
  // Do something here for various values of val
  if (val == 0) {
    // Something
  } else if (val == 1) {
    // Something else
  }
}

function foo()
  var xhr=send_request( "bla", function() {
    var myResult = 0; // Something here based on return values.
    retFunction(myResult);
  });
}
0 голосов
/ 13 июня 2011

Если вы хотите сохранить синхронность, воспользуйтесь предложением Stargazer712.

Вы можете попытаться сохранить вещи асинхронными с чем-то вроде этого:

function foo(callback)
  var xhr=send_request( "bla", function(result) {
     callback(result)
  } );
}


function test(result) {
  // test result here 
  if(result != "what I want")
     foo(test);   // repeat the ajax call under certain conditions
  else
     alert("got it");
}


$(function() {
  foo(test);
});

Это будет повторять запрос ajax, пока ответ не будет соответствовать определенному значению.

0 голосов
/ 13 июня 2011

переменная ret имеет локальную область действия внутри функции.Поэтому каждый раз, когда вы вызываете ее, переменная инициализируется равной 0.

Более того, когда функция возвращает переменную ret, функция send_request (которая устанавливает что-то еще на ret) имеетеще не запущен, из-за чего возвращаемое значение всегда равно 0. После получения возвращенной функции должно быть выполнено ajax-запрос, и функция send_request установила новое значение в ret.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...