Цикл jQuery, выполняется только последний успешный ajax

#jquery

#jquery

Вопрос:

Итак, это сердце моего расширения Chrome [здесь], [ jq это jQuery.noConflict() ] jq('.pam div .fbCurrentActionLink') возвращает каждую ссылку «Тыкать» на Facebook. Он использует .each() для перебора каждого пользователя [иначе говоря, ссылки «тыкать» каждого пользователя], и при успешном выполнении он заменяет текст «Тыкать» жирным и зеленым текстом «Тыкнул».

 function execute()
{
        jq('.pam div .fbCurrentActionLink').each(function () {

        anc=jq(this)
        uid=anc.attr('ajaxify').match(/(d )/)[0]

        //ajax
                var post_form_id = jq('#post_form_id').val();
                var fb_dtsg = jq('input[name=fb_dtsg]').val();
                //use AJAX to submit poke, via their fb id
                jq.ajax({
                        type: 'POST',
                        url: 'ajax/poke.php?__a=1',
                        data: 'uid='   uid   'amp;pokeback=1amp;post_form_id='   post_form_id   'amp;fb_dtsg='   fb_dtsg   'amp;post_form_id_source=AsyncRequest',
                        beforeSend: function(xhr){
                                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
                        },
                        success: function(data, textStatus){
                                anc.html('<b style="color:green !important">Poked</b>');
                        }
                });

        //ajax
        });

}
  

Теперь проблема в том, что, допустим, нужно вернуть 3 нажатия. Он будет выполнять .html () только в последнем цикле. Я не могу понять, почему.

Комментарии:

1. Я не уверен на 100%, но я полагаю, что переменная anc переназначается (даже при успешном завершении) на каждой итерации цикла. Если вы объявляете переменную, используя var anc; в каждом цикле цикла это может решить вашу проблему.

2. К вашему сведению: Никогда не используйте <b> , это устарело в XHTML и настоятельно избегается в HTML5. Используйте <strong> для семантического выделения или <span> иным образом. Никогда не используйте встроенный стиль, это зло. Используйте классы или идентификаторы и внешнюю таблицу стилей для оформления. О, и вы пропускаете точки с запятой и var ключевое слово в ваших объявлениях переменных.

3. Я предполагаю, что переменная «anc» кажется глобальной, и поскольку anc.html () заменяет html вместо добавления к html, он перезаписывается. Я подозреваю, что ваш код выполняется все три раза, но HTML перезаписывается каждый раз, так что отображается только последний.

4. Вы можете извлечь var post_form_id = jq(‘#post_form_id’).val(); var fb_dtsg = jq(‘ввод [имя=fb_dtsg]’).val(); из цикла. Нет необходимости повторно объявлять переменные.

5. У вас также отсутствует точка с запятой после этих двух объявлений anc=jq(this) amp; uid =anc.attr(‘ajaxify’).match(/(d )/)[0]

Ответ №1:

Я думаю, проблема, с которой вы столкнулись, заключается в том, что к моменту выполнения первого вызова ajax значение anc было переопределено. После запуска события success значение anc равно его значению на последней итерации. Чтобы решить эту проблему, вы должны остановить переопределение значений или, во время цикла, вы должны привязать каждый ajax-вызов к элементу, в который будут помещены результаты.

Чтобы привязать вызов ajax к элементу dom, вам необходимо указать define context для вызова ajax.

Попробуйте, я надеюсь, что это должно сработать…

       jq.ajax({
              type: 'POST',
              context: this,        //added line
              url: 'ajax/poke.php?__a=1',
              data: 'uid='   uid   'amp;pokeback=1amp;post_form_id='   post_form_id   'amp;fb_dtsg='   fb_dtsg   'amp;post_form_id_source=AsyncRequest',
              beforeSend: function(xhr){
                    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
              },
              success: function(data, textStatus){
                    $(this).html('<b style="color:green !important">Poked</b>');  
                    //changed to $(this) instead of anc
              }
      });
  

Комментарии:

1. 1, это сработало. Но что это context: this, значит? Кроме того, допустим, я хотел бы получать только один AJAX-запрос одновременно?

2. Контекст связывает вызов AJAX с элементом HTML, так что внутри всех функций, связанных с этим ajax-вызовом (success, beforeSend, error и т.д.), Когда вы используете this указатель, Он указывает на context определение ajax-вызова.

3. Для одновременного выполнения 1 ajax-вызова необходимо async: "false", внутри jq.ajax({ async: "false", /*url,context,data...*/ }); этого параметра отключить asynchronous функциональность AJAX, что означает, что одновременно будет выполняться только 1 ajax-вызов, и как только он завершится, начнется другой.

4. Чтобы быть более конкретным: когда я использовал context: this, this , это ссылка на this указатель, предоставленный .each() циклом. Более типичным context определением было бы что-то вроде context: document.getElementById("results"), но поскольку вызов ajax был внутри .each() цикла, я просто взял this из этого цикла и как бы связал его с вызовом ajax, используя context . Это проблема, с которой вы столкнулись, вызовы ajax не были должным образом привязаны к элементам HTML, которые они изменяли.

5. Ну, я не уверен, что полностью понял ваш второй комментарий.. ну что ж: P Так разве плохо использовать неасинхронный? Это замораживает браузер? Кроме того, LOL! Я думал, что вы и человек, с которым я говорил о точках с запятой, были разными людьми. XD

Ответ №2:

Вы должны префиксить свои переменные на var . В противном случае они не объявляются локально (т.Е. в each ). Если это так, переменная перезаписывается на каждой итерации.

 function execute() {
        jq('.pam div .fbCurrentActionLink').each(function () {
            var anc = jq(this);                              // Added `var`
            var uid = anc.attr('ajaxify').match(/(d )/)[0]; // Added `var`
            ....