Подтвердить что ты не робот

JQuery: ждать завершения функции для продолжения обработки?

Эй, все. У меня, как представляется, тривиальная проблема. У меня есть следующий JavaScript:

$(function() {
    var r = GetResults();

    for(var i = 0; i < r.length; i++) {
        // Do stuff with r
    }
});

function GetResults() {
   $.getJSON("/controller/method/", null, function(data) {
       return data;
   });
}

Из-за того, что я вызываю метод асинхронно, script продолжает выполнение, и когда он встречает цикл for, r, очевидно, пока не получит значения. Мой вопрос: когда у меня есть метод, выполняющий асинхронную операцию, и я зависим от возвращаемых данных в главном блоке, как остановить выполнение до тех пор, пока данные не будут возвращены? Что-то вроде:

var r = GetResults(param, function() {

});

где функция является функцией обратного вызова. Я не могу переместить обработку цикла for в функцию обратного вызова запроса JSON, потому что я повторно использую функции GetResults несколько раз на всей странице, если только я не хочу дублировать код. Любые идеи?

4b9b3361

Ответ 1

переместите блок "do stuff with r" в ваш обратный вызов $.getJSON. вы не можете делать вещи с r до тех пор, пока они не будут доставлены, и первая возможность, которую вы должны будете использовать r, находится в обратном вызове... так что сделайте это.

$(function() {
    var r = GetResults();  
});

function GetResults() {
   $.getJSON("/controller/method/", null, function(data) {
       for(var i = 0; i < data.length; i++) {
           // Do stuff with data
       }
       return data;
   });
}

Ответ 2

Ajax уже дает вам обратный вызов, вы должны его использовать:

function dostuff( data ) {
    for(var i = 0; i < data.length; i++) {
        // Do stuff with data
    }
};
$(document).ready( function() {
    $.getJSON( "/controller/method/", null, dostuff );
});

Ответ 3

Раньше я сталкивался с чем-то подобным. Вам придется запускать вызов ajax синхронно.

Вот мой рабочий пример:

$.ajax({
    type: "POST",
    url: "/services/GetResources",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: '{resourceFileName:"mapedit",culture:"' + $("#lang-name").val() + '"}',
    cache: true,
    async: false, // to set local variable
    success: function(data) {
        localizations = data.d;
    }
});

Ответ 4

Вы можете сделать это:

$(function() {
    PerformCall();        
});

function PerformCall() {
   $.getJSON("/controller/method/", null, function(data) {
       for(var i = 0; i < data.length; i++) {
        // Do stuff with data
       }
   });
}

Ответ 5

Короткий ответ заключается в том, что вы не можете блокировать асинхронную операцию... что, конечно, означает "асинхронный".

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

$(function() {
  GetResults();
});

function GetResults() {
  $.getJSON("/controller/method/", null, function(data) {
    for(var i = 0; i < data.length; i++) {
      // Do stuff with data
    }
  });
}

Ответ 6

Учитывая ваши обновленные требования...

Я не могу переместить обработку цикла в функцию обратного вызова JSON запрос, потому что я повторно использую функциональность GetResults несколько время на всей странице, если только я хотите дублировать код. Любые идеи?

... вы можете изменить GetResults(), чтобы принять функцию в качестве параметра, который затем выполнялся бы как ваш обратный вызов $.getJSON (предупреждение о воздушном коде):

$(function() {
    GetResults(function(data) {
        for(var i = 0; i < data.length; i++) {
            // Do stuff with data
        }
    });
});

function GetResults(callback) {
   $.getJSON("/controller/method/", null, callback);
}

Как вы можете видеть из общего ответа, вам лучше не пытаться бороться с асинхронной моделью программирования jQuery.:)

Ответ 7

Это невозможно.

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

Ответ 8

Переместите обработку данных в обратный вызов:

$(function() {
    GetResults();
});

function GetResults() {
   $.getJSON("/controller/method/", null, function(data) {

       for(var i = 0; i < data.length; i++) {
           // Do stuff with data
       }
   });
}

Ответ 9

Вы можете иметь обратный вызов с параметрами, которые должны хорошо работать...

$(function() {
    GetResults(function(data) {
      for(var i = 0; i < data.length; i++) {
        // Do stuff with data
      }
    });

});

function GetResults(func) {
   $.getJSON("/controller/method/", null, func);
}