Очередь AJAX звонков - PullRequest
       18

Очередь AJAX звонков

7 голосов
/ 25 января 2011

Здравствуйте, я делаю сайт с горизонтальной прокруткой, как: http://vanityclaire.com/

Однако, вместо того, чтобы иметь один большой HTML-файл, после загрузки домашней страницы я использую jQuery .load () для работы с детьми из дома.

В настоящее время я для-каждого div и ajax в нем URL, который находится в названии. Но AJAX возвращается не по порядку, и по мере того, как я добавляю больше страниц, мне не кажется, что расчесывает сервер с более чем 30 запросами http: //.

Как мне синхронно выполнять вызовы AJAX, т. Е. Ждать, пока первый вернется, прежде чем запросить другой, или даже отправить два по очереди.

Я обыскивал и не могу понять, что мне нужно.

Это мой HTML:

<div id="mainLayout" class="fullwidth scrollArea">
    <div class="scrollItems">
      <div id="page-1" class="scrollItem" title="/">
        <div>HOME PAGE CONTENT</div>
      </div>
      <div id="page-2" class="scrollItem" title="/Page2.html">
        <div class="loading"> </div>
      </div>
      <div id="page-3" class="scrollItem" title="/Page3.html">
        <div class="loading"> </div>
      </div>

      <div id="page-4" class="scrollItem" title="/Page4.html">
        <div class="loading"> </div>
      </div>
      <div id="page-5" class="scrollItem" title="/Page5.html">
        <div class="loading"> </div>
      </div>
    </div>
  </div>

И мой JS:

function s_loadingInitialPages() {
    var loadingItems = new Array();
    $(".scrollArea .scrollItem").each(function () {
        if ($(this).attr('title') != '/') {
            var oDelem = $(this);
            loadingItems.push(oDelem);
            //alert('test');
        }
    });

    for (i = 0; i < loadingItems.length; i++) {
        // title attribute is the URL to get
        var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent=';
        $(loadingItems[i]).load(ajaxURL);

    }
}

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

Ответы [ 2 ]

18 голосов
/ 25 января 2011

Хитрость заключается в использовании обратных вызовов.Вы делаете один вызов ajax, и при его успешном обратном вызове вы делаете следующий.

Чтобы сделать это, просто добавьте их всех в очередь и оберните вокруг себя обертку, которая отправляет их по одному.

Я написал один несколько дней назад.Я покажу вам реализацию через секунду.

// Buffer class. Has a public append method that expects some kind of Task.
// Constructor expects a handler which is a method that takes a ajax task
// and a callback. Buffer expects the handler to deal with the ajax and run
// the callback when it's finished
function Buffer(handler) {
    var queue = [];

    function run() {
        var callback = function () {
             // when the handler says it's finished (i.e. runs the callback)
             // We check for more tasks in the queue and if there are any we run again
             if (queue.length > 0) {
                  run();
             }
        }
        // give the first item in the queue & the callback to the handler
        handler(queue.shift(), callback);
    } 

    // push the task to the queue. If the queue was empty before the task was pushed
    // we run the task.
    this.append = function(task) {
        queue.push(task);
        if (queue.length === 1) {
            run();
        }
    }

}

// small Task containing item & url & optional callback
function Task(item, url, callback) {
    this.item = item;
    this.url = url;
    this.callback = callback
}

// small handler that loads the task.url into the task.item and calls the callback 
// when its finished
function taskHandler(task, callback) {
    $(task.item).load(task.url, function() {
        // call an option callback from the task
        if (task.callback) task.callback();
        // call the buffer callback.
        callback();
    });
}

// create a buffer object with a taskhandler
var buffer = new Buffer(taskHandler);

for (i = 0; i < loadingItems.length; i++) {
    // title attribute is the URL to get
    var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent=';
    buffer.append(new Task(loadingItems[i], ajaxURL));
}

Извинения за стену кода.Просто реализуйте свои собственные задачи и обработчик.Буфер будет работать до тех пор, пока обработчик вызывает второй аргумент (обратный вызов), когда он завершит обработку задачи.

Затем просто передайте ему задачу и обработчик.Обработчик выполняет ajax и вызывает обратный вызов из буфера, когда возвращается ajax.

Для вашего конкретного примера, если загрузка занимает много времени, то загрузка всех 30. Это займет много времени.ajax - это чтобы сервер выполнял параллельные операциипорядок.Это включает использование $ .ajax и добавление отслеживания порядка каким-либо образом.

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

0 голосов
/ 02 августа 2017

Большинство браузеров могут обрабатывать 6 или более одновременных ajax-запросов к одному домену.
http://www.browserscope.org/?category=network&v=top

Если ваш скрипт размещает 30 ajax-запросов одновременно, первые 6 запросов пройдут очень быстро.После этого браузер может начать назначать произвольные периоды ожидания до 5 секунд.Chrome является ярким примером такого поведения.

Запросы 1-6 возвращаются за 5 мс.

Запросы 7-12 возвращаются за 5,005 мс.

Запросы 11-18 возвращаютсячерез 10,005 мс.

Запросы 19-24 возвращаются за 15,005 мс.

Запросы 25-30 возвращаются за 20,005 мс.

Я рекомендую создать очередь обратных вызовов функций для обработкивсе ajax-запросы вашего приложения и обрабатывают не более 6 из них одновременно.

var ajaxCownt = (ajaxCownt == null ? 0 : ajaxCownt);  // Make limit globally accessible.
var ajaxKue = (ajaxKue == null ? [] : ajaxKue);  // Make queue globally accessible.

function doMyAjaxRequest() {
console.log("doing ajax request.");
// Implement ajax request, here.
}

for (var i = 1;i <= 30;i++) {
ajaxKue.push( function() { doMyAjaxRequest() } ); // Add request to queue.
}

while (ajaxCownt != null && ajaxCownt < 6 && ajaxKue != null && ajaxKue.length && ajaxKue.length > 0) {
ajaxCownt++;
console.log("incrementing pending ajax requests counter by 1.");
ajaxKue.shift().call();
};

// Register an event to detect when an ajax request completes.
// Allow for an additional ajax request to be processed.
$( document ).ajaxComplete(function() {
    if (ajaxCownt && ajaxCownt > 0) {
        ajaxCownt--;
        console.log("decrementing pending ajax requests counter by 1.");
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...