Как я могу группировать jQuery AJAX запросы? - PullRequest
1 голос
/ 22 декабря 2011

У меня есть некоторый код, который выглядит следующим образом (я пропустил части, которые не важны для вопроса):

$.ajax({  
    type: "POST",  
    url:  "prepXML.php",  
    data: "method=getartists&user=" + userName + "&amount=" + amount,  
    dataType: "xml",
    success: function(xml) { 
        $("artist", xml).each(function(){
            // calculate and output some stuff and then call getTracks()
            getTracks(artistName, artistNamePOST, artistPlaycount, divId, artistId);
        }); 
    }
});  

function getTracks(artistName, artistNamePost, artistPlaycount, divId, artistId){
    $.ajax({  
        type: "POST",  
        url:  "prepXML.php",  
        data: "method=gettracks&user=" + userName + "&artist=" + artistNamePOST + "&playcount=" + artistPlaycount,  
        dataType: "xml",
        success: function(xml){
            // calculate and output some stuff
        });                     
    }
});  

Когда он запускается, он вызывает getTracks () пятьдесят раз и выполняет довольно небольшую (серверную) загрузку ЦП за очень короткое время, пока все не будет выполнено. Я хотел бы сгруппировать запросы AJAX getTrack (), например, по 5 раз, подождать, пока эти пять не будут выполнены, затем вызвать следующие пять, дождаться, когда следующие пять будут выполнены, вызвать следующие пять и т. Д. Цель этого состоит в том, чтобы делать меньше запросов в одно и то же время (меньше и более равномерно распределять нагрузку на процессор).

Я не уверен, как или даже если это можно сделать, так как это отчасти превосходит AJAX, но я все же хотел бы сделать эту работу, если это возможно. Может ли кто-нибудь, пожалуйста, указать мне правильное направление? Спасибо.

Чтобы лучше понять, для чего мне это нужно и что делает приложение, вот ссылка на приложение . его можно попробовать с любым последним ником (если у вас его нет, вы можете использовать мой - "pootzko"). Я надеюсь, что мне разрешено помещать ссылку в сообщении (?), Если нет, не стесняйтесь удалить ее ..

Ответы [ 4 ]

1 голос
/ 22 декабря 2011

Мое решение состоит в том, чтобы обработать все данные об исполнителе в массив, а затем начать выполнение .ajax() запросов в пакетах по 5. Когда эти 5 запросов выполнены, следующий пакет выполняется и т. Д.

ЗДЕСЬ - рабочая демонстрация.

// just success changed
$.ajax({  
  type: "POST",  
  url:  "prepXML.php",  
  data: "method=getartists&user=" + userName + "&amount=" + amount,  
  dataType: "xml",
  success: function(xml) {
    var data = [];
    // prepare the data
    $("artist", xml).each(function(){
        data.push({ name: artistName /** rest of data */ } );
    }); 
    // start processing the data
    processData(data, 0);
  }
});  

// process the data by sending requests starting from index
function process(data, index) {
  var xhrs = [];
  for (var i = index; i < index + 5 && i < data.length; i++) {
    (function(data) {
       xhrs.push($.ajax({  
         type: "POST",  
         url:  "prepXML.php",  
         data: "method=gettracks&user=" + data.name /** rest of the data */  
         dataType: "xml",
         success: function(xml) {
           // calculate and output some stuff
         }
       }));
     })(data[i]);
   }

  // when current xhrs are finished, start next batch
  $.when.apply(this, xhrs).then(function() { 
    index += 5; 
    if (index < data.length) {
      process(data, index); 
    }
  });
}
1 голос
/ 22 декабря 2011

Либо включите всю информацию о дорожке в данные, которые возвращаются из getartists ИЛИ звоните только getTracks, когда кто-то хочет просмотреть дорожки для определенного исполнителя.

, например

Отображение всех исполнителей и опции «Просмотр треков». Только когда вы нажмете эту кнопку, вы получите треки.

Для меня это лучший вариант, потому что, если вы загружаете ВСЕ треки для ВСЕХ артистов, то есть много данных, которые, вероятно, не нужны. Никто не захочет просматривать всех исполнителей и все треки исполнителей (если только они этого не хотят).

1 голос
/ 22 декабря 2011

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

Но может сработать что-то вроде следующегоделать только пять запросов одновременно:

$.ajax({  
    type: "POST",  
    url:  "prepXML.php",  
    data: "method=getartists&user=" + userName + "&amount=" + amount,  
    dataType: "xml",
    success: function(xml) { 
      var artists = $("artist", xml),
          i = 0,
          c = 0;

      function getTracksComplete() {
         if (--c === 0)
            nextBatch();
      }

      function nextBatch() {
         for(; c < 5 && i < artists.length; i++, c++) {
            // artists[i] is the current artist record    
            // calculate and output some stuff and then call getTracks()
            getTracks(artistName, artistNamePOST, artistPlaycount, divId, artistId,
                      getTracksComplete); 
         }
      }

      // Optional - if you need to calculate statistics on all the artists
      // then do that here before starting the batches of getTracks calls
      artists.each(function() { /* do something */ });

      // Kick of the first batch of 5
      nextBatch();
   } 
});

function getTracks(artistName, artistNamePost, artistPlaycount, divId, artistId,
                   callback){
    $.ajax({  
        type: "POST",  
        url:  "prepXML.php",  
        data: "method=gettracks&user=" + userName + "&artist=" + artistNamePOST + "&playcount=" + artistPlaycount,  
        dataType: "xml",
        success: function(xml){
            // calculate and output some stuff
        },
        complete : function() {
            if (callback) callback();
        });                     
    }
});

Выше было просто у меня на голове (поэтому у меня не было времени построить его в масштабе или нарисовать), но идеязаключается в том, что вместо использования .each() для циклического прохождения всех исполнителей мы будем кэшировать объект jQuery и выполнять несколько операций одновременно.Вызов функции nextBatch() (которая является локальной для обработчика успеха и, следовательно, имеет доступ к локальным переменным), запустит цикл, который вызывает getTracks() только 5 раз, но начинает обработку с того места, где мы остановились в предыдущий раз.Между тем getTracks() был немного обновлен, чтобы принимать функцию обратного вызова, поэтому, когда его ajax-вызов завершается (и обратите внимание, что мы делаем это по завершении, а не успешно в случае ошибок), он может сообщить основному процессу, что онзакончилВ рамках обратного вызова мы отслеживаем, сколько из них завершено, и когда все они снова наберут nextBatch().

0 голосов
/ 22 декабря 2011

Трудно четко понять логику вашего приложения, но я думаю, что лучше было бы собрать ранее все данные, которые нужно отправить (50 записей в объекте JSON), а затем вызвать функцию getTracks только один раз, передав только один Объект JSON.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...