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 несколько раз на всей странице, если только я не хочу дублировать код. Любые идеи?
Ответы
Ответ 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);
}