2010-07-13 4 views
10

У меня возникла проблема при использовании функций jquery .each() и .ajax() вместе. Я использую .each() для циклического перехода по 5 элементам и выполняю вызов .ajax() для каждого из них. Моя проблема в том, что я хочу, чтобы цикл продолжался, когда ответ был получен от каждого запроса ajax. В настоящее время все 5 элементов зацикливаются, выполняется 5 запросов ajax, затем возвращается 5 ответов.JQuery вызов ajax в каждом цикле

Hers простой пример:

$(".element").each(function() { 
    var id= $(this).find(('txtId').val(); 
    $.ajax({ 
     type: "POST", 
     url: "/Handlers/Handler.ashx", 
     data: "ID=" + id, 
     success: function(xml){ 

     // I would like the each() loop to pause until this is hit, 
     // and some additional logic can be performed. 

     } 
    }); 

}); 

Приветствия.

ответ

10

Вы можете использовать опцию async для этого, чтобы каждый запрос синхронные (= выполнение привал сценария до каждого запроса завершен):

асинхронной По умолчанию все запросы отсылаются асинхронно (т.е. это по умолчанию установлено значение true). Если вам нужны синхронные запросы, установите для этого параметра значение false. Междоменные запросы и dataType: запросы «jsonp» не поддерживают синхронную работу. Обратите внимание, что синхронные запросы могут временно блокировать браузер, отключая любые действия, пока запрос активен.

но, как уже говорилось в документации, это очень обескураживает, так как это может заморозить браузер, если запрос зависает или истекает время.

Было бы лучше изменить архитектуру вашего кода таким образом, чтобы он мог работать с классическими функциями обратного вызова, если это вообще возможно.

+4

Приветствия за помощь, я пошел с вашим предложением и изменил структуру моего кода, я удалил цикл и вместо этого использовал рекурсию. Сейчас работает нормально. – DazzledKid

2

У Пекки есть правильный ответ. Вам просто нужно отредактировать свой скрипт, как показано ниже.

$(".element").each(function() { 
    var id= $(this).find(('txtId').val(); 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "/Handlers/Handler.ashx", 
     data: "ID=" + id, 
     success: function(xml){ 

     } 
    }); 

}); 
+0

Я пробовал это, я могу понять, почему он очень обескуражен. По-видимому, это значение false приводит к тому, что мой браузер замораживается до тех пор, пока все ответы не будут получены, и цикл завершится. – DazzledKid

+0

Я не уверен, что вы ожидали. Если вы хотите, чтобы сценарий приостанавливался и ожидал ответа, он будет делать именно эту паузу и ждать. Возможно, вам стоит объяснить, что именно вы пытаетесь достичь, поскольку может быть лучший способ. Вероятно, есть лучший способ достичь желаемых конечных результатов с помощью другого алгоритма. – YonahW

0

Я рад сказать, что есть способ ... но это немного противно.

Если вы уверены, что запрос должен что-то вернуть, вы можете удалить часть «tryIteration».

$(document).ready(function() { 

     loop(".buttonsPromotion", 0); 

}); 

function loop(elements, tryIteration) { 
//HOW MANY TRIES UNTIL WE STOP CHECKING 
if(tryIteration<7){ 

    $(elements).each(function() {    
     var actuel = $(this); 
     $.ajax({ 
      url: "write your link here", 
      data: {}, 
      dataType: 'json', 
      async: true, 
      success: function(data){ 
       //HERE WE KNOW THE AJAX REQUEST WENT OK 
       actuel.addClass('AjaxOK');  
      }, 
      error:function(thrownError){ 
       console.log(thrownError); 
       //WE MAKE ANOTHER EACH ON ALL ELEMENT THAT WENT BAD 
       var elemToRetry = actuel.not('AjaxOK'); 
       loop(elemToRetry, ++tryIteration); 
      } 
     }); 

    }); 
} 
} 
+0

Почему бы не просто вырваться из каждого цикла, когда первый запрос ajax возвращает успех? – markus