jquery: Порядок выполнения

Следующий мой код:

$(document).on("click",".ball_link", function makeDiv(){
    function fetchLevels(){
        $.getJSON('fetch_level.php',{level: clicked_ball}, function(data) {
        $.each(data, function(i,name) {
                alert(name.level_id); //Line 1
            });
        });
    }
    fetchLevels();
    alert(name.level_id); //Line 2
    while (//some condition){
        alert("hi 2"); //Line 3
    }
});

Требуемый порядок исполнения:

Линия 1

Строка 2 (со значением, аналогичным значению в строке 1)

Строка 3

Фактический порядок исполнения:

Строка 2 (значение: undefined)

Строка 3

Строка 1 (правильное значение)

Как мне контролировать порядок выполнения этих строк, чтобы получить нужные строки с правильными значениями?


person soundswaste    schedule 24.09.2012    source источник
comment
@SenthilKumar: Никогда не делай этого.   -  person Bergi    schedule 24.09.2012
comment
@Bergi, ты можешь мне сказать, почему это плохо?   -  person Senthil Kumar    schedule 24.09.2012
comment
потому что async: false заморозит интерфейс до завершения вызова ajax   -  person Fabrizio Calderan    schedule 24.09.2012
comment
@Bergi, спасибо !! я не знал этого!   -  person Senthil Kumar    schedule 24.09.2012


Ответы (4)


Поскольку вызов ajax является асинхронным, либо вы перемещаете весь код в обратном вызове успеха, либо используете отложенные объекты для обработки правильного порядка выполнения.

function fetchLevels() {

    $.getJSON('fetch_level.php', { level: clicked_ball })

    .done(function(data) {
        $.each(data, function(i,name) {
            alert(name.level_id); //Line 1
        });

        alert(name.level_id); //Line 2
        while (//some condition) {
            alert("hi 2"); //Line 3
        }
    });
}

fetchLevels();

или, в качестве альтернативы, вы можете использовать это

function fetchLevels() { 
    return $.getJSON('fetch_level.php', { level: clicked_ball })
}

$.when(fetchLevels()).done(function(data) {
    $.each(data, function(i,name) {
          alert(name.level_id); //Line 1
    });

    alert(name.level_id); //Line 2
          while (//some condition) {
             alert("hi 2"); //Line 3
         }
    });
})
person Fabrizio Calderan    schedule 24.09.2012

Обычно в вашем сценарии вы вызываете .ajax и выполняете свою обработку с помощью команды успеха, например:

$.ajax({
  url: myUrl,
  dataType: 'json',
  data: myData,
  success: function(data) {
    // do stuff here.
  }
});

Если вам действительно нужно кодировать, как вы предложили, вы можете использовать async: false, например:

$.ajax({
  url: myUrl,
  dataType: 'json',
  async: false,
  data: myData,
  success: function(data) {
    // set variable here, then work with it outside the function
  }
});
person Chris Dixon    schedule 24.09.2012
comment
Второй вариант, да, и я не советовал второй вариант. Первый вариант - это то, как я подхожу к решению. - person Chris Dixon; 24.09.2012

Поместите строку 2 и строку 3 в обратный вызов $.getJSON, иначе строка 1 будет выполняться асинхронно после завершения обратного вызова, а остальные выполняются синхронно.

person Konstantin Dinev    schedule 24.09.2012

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

$(document).on("click", ".ball_link", function makeDiv() {
     $.getJSON('fetch_level.php', {
         level: clicked_ball
     }, function (data) {
         $.each(data, function (i, name) {
             alert(name.level_id); //Line 1
         });

         fetchLevels();
         alert(name.level_id); //Line 2
         while ( //some condition){
             alert("hi 2"); //Line 3
         }
     });
 });
person Bergi    schedule 24.09.2012