Попытка использовать отложенные объекты и $.когда выполнять несколько вызовов AJAX

#javascript #jquery #ajax

#javascript #jquery #ajax

Вопрос:

Итак, основываясь на этом руководстве по Medium (https://medium.com/coding-design/writing-better-ajax-8ee4a7fb95f#.d7ymg99mp ), я пытаюсь использовать отложенные массивы, ajax-запросы и jQuery.метод when для выполнения нескольких запросов ajax и получения результата от каждого из них.

Вот код для того, что я делаю

 function updateAllGoingButtons(){
    var dataToPass = {};
    var deferreds = [];

    $('.btn-group').find('button').each(function(){
       console.log($(this).attr('id'));
       dataToPass.button = $(this).attr('id');
       var ajax = $.ajax({
          url: '/update-buttons',
          method: 'post',
          data: dataToPass,
          dataType:'json'
       });

       deferreds.push(ajax);

       $.when.apply($, deferreds).then(function(){

       });
    });
}
  

Возникает путаница в том, как использовать эту функцию $.when и где я могу получить доступ к данным, возвращенным в вызов ajax.

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

Ответ №1:

Вы просто вызываете when слишком рано. Сделайте это вне each цикла, после того, как вы запустили все свои вызовы ajax и получили их обещания в массиве:

 function updateAllGoingButtons(){
    var dataToPass = {};
    var deferreds = [];

    $('.btn-group').find('button').each(function(){
       console.log($(this).attr('id'));
       dataToPass.button = $(this).attr('id');
       var ajax = $.ajax({
          url: '/update-buttons',
          method: 'post',
          data: dataToPass,
          dataType:'json'
       });

       deferreds.push(ajax);

    });

    $.when.apply($, deferreds).then(function(){     // <=== Moved this
                                                    // <===
    });                                             // <===
}
  

Результаты этих вызовов ajax будут предоставлены вашей then функции в виде последовательности отдельных аргументов. Каждый аргумент будет представлять собой массив с тремя записями, соответствующими трем аргументам, обычно передаваемым success функциям. Поскольку вы имеете дело с массивом, вы, вероятно, захотите получить к ним доступ через arguments псевдомассив. Также всегда полезно иметь обработчик отклонения (второй аргумент then или альтернативно использовать catch с последними версиями jQuery):

 $.when.apply($, deferreds).then(
    function() {
        var n;
        for (n = 0; n < arguments.length;   n) {
             console.log("Result "   n, arguments[n][0]);
        }
    },
    function() {
        // At least one request failed
    }
);
  

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

1. Хорошо, но я все еще не понимаю, как получить доступ к данным, переданным обратно в вызов AJAX изнутри метода $.when! Как мне это сделать? Когда я пытаюсь console.log(deferreds) изнутри этого метода, я не получаю никаких выходных данных.

2. @ZaidHumayun: Как сказано в when документации : «Аргументы, переданные обратным вызовам, предоставляют разрешенные значения для каждого из отложенных вызовов и соответствуют порядку, в котором отсрочки были переданы в jQuery. when().» (за которым следует пример; найдите «пицца» на этой странице). В основном: результаты являются дискретными аргументами для обратного вызова.

3. Ну, я, кажется, неправильно понимаю это. В документации похоже, что отложенные объекты явно разрешаются, тогда как я просто использую res.send для возврата данных. Будет ли мой случай по-прежнему работать? Потому что я пытался передавать параметры и регистрировать их в обратном вызове then, но безуспешно. $.when.apply($, deferreds).then(function(a,b,c,d,e) { console.log(a); console.log(b); console.log(c); console.log(d); });

4. @ZaidHumayun: Да. В этом примере они создают и разрешают отсрочки, но в вашем случае использования вы используете те, которые созданы и разрешены ajax .

5. @ZaidHumayun: Да, вы должны видеть что-то из этой консоли. регистрируйте инструкции, если все вызовы были успешными; Я делаю: jsfiddle.net/57z7qycL Похоже, что ошибка возникает по крайней мере в одном вызове. Поскольку вы не передаете вторую функцию then , вы не получаете уведомления об ошибке. Обратите внимание, что каждый результат в случае ajax представляет собой массив с тремя записями (которые соответствуют трем аргументам success , которые обычно получаются, поэтому вы обычно хотите [0] ).