2016-05-23 4 views
0

У меня есть функция в JS содержит цикл, который вызывает вызов AJAX на каждой итерации. Вызов вставляет checked элементов в БД и возвращает результаты этих элементов на той же странице в следующем разделе.Как замедлить вызов Ajax?

Проблема заключается в том, что когда я проверяю, например, 4 из 3 групп, на страницу добавляются только флажки последней группы. Однако, когда я использую alert(), я могу видеть все элементы.

Я использовал setTimeout, но я получил ошибку в коде. Я также добавил строки, чтобы дать больше времени на вызов AJX, но проблема остается. Поэтому я задаюсь вопросом, есть ли решение для замедления кода без использования alert().

Это мой сценарий:

addAptitudeField : function(currentAutocompleteField, idChamp) { 

    var currentAutocompleteFieldBind = currentAutocompleteField; 
    var idChampBind = idChamp; 

    window.setTimeout(function() { 

     // Code ... 

     var paramDwr = {}; 
     var newDivName = "div" + idChamp + lastValueId; 
     paramDwr[attributs.r_divId] = newDivName; 
     paramDwr[attributs.r_currentValue] = currentValue; 
     paramDwr[attributs.r_hiddenIdsField] = hiddenIdsField.id; 
     paramDwr[attributs.r_lastValueId] = lastValueId; 
     paramDwr[attributs.r_itemmod] = nbAptitudesCat % 2 == 0; 

     // setTimeout (RepertoireDwr.ligneSuppEtSpanMessage, 1000) doesn't work 

     RepertoireDwr.ligneSuppEtSpanMessage(paramDwr, function(ajaxPage) { 
      divCategorie.update(divCategorie.innerHTML + ajaxPage.texte); 
      aptitudeAvecDetail.remetsValeursStockees(); 
      var btnSuppression = $(newDivName).getElementsByTagName('img')[0]; 
      btnSuppression.setAttribute("onclick", "formulaireFiche.updateCSS('" + newDivName + "');" + btnSuppression.getAttribute("onclick") + "fiche.updateCategorieSuppressionAptLieeUo(\'divCat" + currentCategorie + "\');"); }); 
      } 
     // 
     // alert() : It works in this case. 
     // 

     // for (var i=0; i<5000000; i++) ; it doesn't work 

     }, 400); 
    } 

Заранее спасибо за вашу помощь и время.

+0

Что петля? Как это «не работает»? Какую ошибку вы получаете? На самом деле непонятно, о чем вы спрашиваете, но это определенно звучит так, будто вы пытаетесь решить проблему, создавая другую проблему. – David

+0

Я спас свой вопрос к тому, что, я думаю, вы имеете в виду. Пожалуйста, ознакомьтесь с нашими исправлениями – Martijn

+0

Большое спасибо @Martijn, yeap, это именно то, о чем я прошу, я извиняюсь за свой язык. – Chinovski

ответ

2

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

В конструкции jQuery AJAX есть опция async:false,, которая задерживает выполнение сценария от продолжения ДОПОЛНИТЕЛЬНОЙ обработки AJAX. Излишне говорить, что если в AJAX что-то не так, браузер может замерзнуть. Многое зависит от того, кто ваши пользователи, и объем трафика - на нескольких моих 10-пользовательских внутренних проектах это было приемлемым решением.

$.ajax({ 
    async: false, 
    type: 'post', 
    url: 'ajax/ax.php', 
    data: 'request=', 
    success: function(d){ 
     if (d.length) alert(d); 
    } 
}); 

Ref:

What does "async: false" do in jQuery.ajax()?


Чем лучше идея, однако, смотреть в интерфейс Обещания, с методами, как .when() и .then()

Ссылки:

https://jsfiddle.net/v86bc028/2/

http://jqfundamentals.com/chapter/ajax-deferreds#

http://digitizor.com/jquery-html-callback-function-using-promise/#

how does jquery's promise method really work?

+0

Он работает знает, я положил асинхронное значение false, и он отлично работает, спасибо – Chinovski

1

Проблема, с которой вы сталкиваетесь, связана с асинхронными функциями или A в AJAX. Если вы не знаете, что такое асинхронная функция, есть много других, которые могут объяснить это лучше, чем я могу, поэтому дайте это Google.

Что происходит без alert(), там есть код, который делает 4 звонка, но все 4 отправляются, прежде чем вы получите ответ на любой из них. С alert() (или setTimeout) вы даете коду время для получения каждого ответа на вызов до того, как будет сделан следующий.

Существует несколько способов приблизиться к этому, первым способом является вызов следующего вызова после первого получения ответа. Второй способ - использовать функцию асинхронного вызова для одновременного вызова всех 4 в разных цепочках (?). Я не лучший, объясняя эту часть, но есть много кода, который можно найти в SO и онлайн.

+0

Yeap, это именно то, что я пытаюсь сделать, это продолжить следующий вызов после первого ответа, используя setTimeout и многие инструкции, чтобы дать время Ajax, но никаких хороших результатов. Благодарим вас за ответ – Chinovski

1

Я думаю, что у вас есть более общая проблема в вашем коде, поскольку вам, кажется, нужно отложить выполнение, чтобы ждать до sth. else закончен, вместо того, чтобы быть объявленным, когда это будет сделано.

линия, которая раздражает меня больше всего, это один

divCategorie.update(divCategorie.innerHTML + ajaxPage.texte); 

что именно обновление делает? Как это реализовано? Я предполагаю, что это действительно так. divCategorie.innerHTML += ajaxPage.texte;
Это очень неблагоприятно, так как браузер должен разбирать и перестраивать, что бы там ни было в divCategorie.innerHTML.

Просто добавление новой разметки было бы лучше.

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

Вроде как это:

addAptitudeField : function(currentAutocompleteField, idChamp) { 

    var currentAutocompleteFieldBind = currentAutocompleteField; 
    var idChampBind = idChamp; 

    //this is done immediately, and therefore preserves the order of the loop, 
    //without any delays/timeouts 
    var placeholder = document.createElement("div"); 
     placeholder.className = "placeholder"; 
     placeholder.style.display = "none"; 
    divCategorie.appendChild(placeholder); 

    window.setTimeout(function() { 

     // Code ... 

     var paramDwr = {}; 
     var newDivName = "div" + idChamp + lastValueId; 
     paramDwr[attributs.r_divId] = newDivName; 
     paramDwr[attributs.r_currentValue] = currentValue; 
     paramDwr[attributs.r_hiddenIdsField] = hiddenIdsField.id; 
     paramDwr[attributs.r_lastValueId] = lastValueId; 
     paramDwr[attributs.r_itemmod] = nbAptitudesCat % 2 == 0; 

     // setTimeout (RepertoireDwr.ligneSuppEtSpanMessage, 1000) doesn't work 

     RepertoireDwr.ligneSuppEtSpanMessage(paramDwr, function(ajaxPage) { 
      //convert the passed text into a DocumentFragment 
      var frag = fragment(ajaxPage.texte); 

      //replacing the placeholder with the fragment 
      divCategorie.insertBefore(frag, placeholder); 
      divCategorie.removeChild(placeholder); 

      aptitudeAvecDetail.remetsValeursStockees(); 
      var btnSuppression = $(newDivName).getElementsByTagName('img')[0]; 
      //this is also pretty horrible to me: 
      btnSuppression.setAttribute("onclick", "formulaireFiche.updateCSS('" + newDivName + "');" + btnSuppression.getAttribute("onclick") + "fiche.updateCategorieSuppressionAptLieeUo(\'divCat" + currentCategorie + "\');"); }); 
      } 
     }, 400); 
    } 

Я думаю, что вы должны сделать некоторые основные рефакторинга. И взгляните на Обещания.

// * -> DocumentFragment 
//strings/primitives are parsed as HTML-markup, 
//null/undefined is ignored 
//Arraylike structures are parsed recursively 
var fragment = (function(container){ 
    return function(src){ 
     return reducer(document.createDocumentFragment(), src); 
    } 

    function reducer(frag, node){ 
     var i, len, fc, c, r; 
     if(node === Object(node)){ 
      if("nodeType" in node){ 
       //dom nodes 
       frag.appendChild(node); 
      }else{ 
       //Arraylike structures, like NodeLists or jQuery-Objects, or just plain Arrays 
       for(i = 0, len = ("length" in node && node.length)|0, r = reducer; i < len; (i in node) && r(frag, node[i])); 
      } 
     }else if(node != null) { 
      //strings (all primitives) 
      for((c=container).innerHTML = node; fc = c.firstChild; frag.appendChild(fc)); 
     } 
     return frag; 
    } 
})(document.createElement("div")); 
+0

Благодарим за ответ, во-первых, функция обновления позволяет показать, какие категории уже были добавлены в поле, поэтому каждый раз, когда я добавляю новую категорию, эта функция вставляет ее в старый список. Я признаю, что код не ясен, он старый и сложный для меня (я новичок в JS). Я попробую с вашим кодом и посмотреть, что я могу с ним сделать. Еще раз спасибо. – Chinovski

Смежные вопросы