Определение области действия функции Javascript - PullRequest
2 голосов
/ 28 мая 2011

Это очень ясно, я не понимаю, как функции ограничены в Javascript.Вот последний пример:

function riseData() { 
    var jsonResult;
    $.ajax({
        success: function(data, textStatus, jqXHR){
            jsonResult = jqXHR.responseText;
            alert("Inside: " + jsonResult);
        },          
        error: function (jqXHR, textStatus, errorThrown) {  
            $('#errLog').append('<br>Status: ' + qXHR.statusText);                  
        }
    });
    return jsonResult;
}

$(document).ready(function(){
    var intervalID = setInterval('UTCclock()',100); 
    alert("Outside: " + riseData());                            
});

Когда я выполняю это, оповещение «Внутри» работает правильно, но оповещение «Снаружи» отображает «не определено», даже если riseData (), очевидно, определяется только несколькими строками.ранее.Ранее в коде был $ .ajaxSetup, который определяет параметры для вызова ajax.Вызов ajax успешно возвращает запрошенные данные в предупреждении «Внутри».

У меня просто нет ни малейшего понятия, как сделать необходимые данные (jqXHR.responseText) доступными для других частей скрипта.

Может ли кто-нибудь указать мне на «Javascript Scoping for Dummies»"Как решить эту проблему?

Ответы [ 2 ]

5 голосов
/ 28 мая 2011

Ваш пример очень хорош.Ваша проблема в том, что вы не понимаете последствий того, что JavaScript в основном асинхронный.

Позвольте мне перейти к вашему примеру, чтобы показать вам.

  1. Запустится ваш обработчик документов.
  2. Он вызывает riseData.
  3. riseData объявляет переменную, jsonResult.
  4. riseData вызывает $.ajax, которая планирует выполнение запроса AJAX,но ответ произойдет позже.
  5. Поскольку $.ajax обычно неблокируемый / асинхронный, riseData продолжается и возвращает jsonResult.Поскольку jsonResult еще не было назначено, поскольку запрос AJAX не был выполнен, возвращается значение по умолчанию undefined.
  6. В обработчике готовности документа вы получите alert("Outside: "+undefined);.

Цикл событий через несколько миллисекунд, это происходит:

  1. Запрос AJAX завершен.jQuery перенаправляет это на ваш обратный вызов.
  2. jsonResult установлено, но riseData уже возвращено.
  3. alert внутри riseData предупреждает о новых данных после того, какобработчик готовых документов уже предупредил undefined.

Существует два решения этой проблемы.Первое решение простое, но часто приводит к ухудшению взаимодействия с пользователем.Это решение заключается в добавлении опции async: false к $.ajax.Это заставляет $.ajax блокировать и замораживать браузер.

Вторым решением является использование асинхронного стиля практически для всего.Это означает, что riseData принимает обратный вызов и вызывает его в обработчике ответа AJAX.Вот ваш код, преобразованный с помощью этого метода:

function riseData(callback) { 
    $.ajax({
        success: function(data, textStatus, jqXHR){
            var jsonResult = jqXHR.responseText;
            alert("Inside: " + jsonResult);
            callback(jsonResult);
        },          
        error: function (jqXHR, textStatus, errorThrown) {  
            $('#errLog').append('<br>Status: ' + qXHR.statusText);                  
        }
    });
}

$(document).ready(function(){
    //var intervalID = setInterval('UTCclock()',100); 
    // Unrelated, but it's better to pass a
    // function into setInterval than a string.
    var intervalID = setInterval(UTCclock, 100);
    riseData(function(jsonResult) {
        alert("Outside: " + jsonResult);
    });
});
0 голосов
/ 28 мая 2011

Это только частичная проблема. Ваш ajax-вызов асинхронный, поэтому функция riseData () возвращает значение до выполнения ajax-вызова. Попробуйте установить переменную вне метода.

var jsonResult;

function riseData() { 

    $.ajax({
...

jsonResult должен быть доступен не только в riseData (), но и вне. Тем не менее, у вас все еще будет проблема, когда именно он будет заполнен.

Ссылка для более подробного объяснения:

Какова область видимости переменных в JavaScript?

...