jQuery: ждать завершения функции, чтобы продолжить обработку? - PullRequest
17 голосов
/ 21 сентября 2009

Привет всем. У меня есть, кажется, тривиальная проблема. У меня есть следующий 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;
   });
}

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

var r = GetResults(param, function() {

});

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

Ответы [ 9 ]

13 голосов
/ 21 сентября 2009

переместите ваш блок "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;
   });
}
7 голосов
/ 21 сентября 2009

Я сталкивался с чем-то похожим раньше. Вам придется выполнять вызов 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;
    }
});
7 голосов
/ 21 сентября 2009

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 голосов
/ 21 сентября 2009

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

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

function PerformCall() {
   $.getJSON("/controller/method/", null, function(data) {
       for(var i = 0; i < data.length; i++) {
        // Do stuff with data
       }
   });
}
2 голосов
/ 21 сентября 2009

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

Я не могу переместить цикл обработки в функцию обратного вызова 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. :)

2 голосов
/ 21 сентября 2009

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

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

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

function GetResults() {
  $.getJSON("/controller/method/", null, function(data) {
    for(var i = 0; i < data.length; i++) {
      // Do stuff with data
    }
  });
}
0 голосов
/ 21 сентября 2009

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

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

});

function GetResults(func) {
   $.getJSON("/controller/method/", null, func);
}
0 голосов
/ 21 сентября 2009

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

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

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

       for(var i = 0; i < data.length; i++) {
           // Do stuff with data
       }
   });
}
0 голосов
/ 21 сентября 2009

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

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

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