Pull to refresh

Простой способ организации очереди из AJAX-запросов

Reading time2 min
Views3.9K
Постановка задачи

Асинхронные запросы являются удобным способом разгрузить пользователей сайта от избытка информации, которая «сваливается» на них после отображения страницы. Рассмотрим классический пример — список товаров в интернет-магазине. Пользователь выполняет какой-либо поисковый запрос, в результате чего ему отображается компактный список найденных товаров. Например, это могут быть только одни названия. Под каждым из названий стоит ссылка «подробнее», после клика на которую под названием откроется дополнительный блок, уже с подробной информацией о товаре. Удобство пользователя налицо — быстро пробежав глазами весь список, он «прокликает» только заинтересовавшие его товары, и быстро перейдет к следующим страницам. Выгодно это и со стороны сервера — меньшая нагрузка, меньше исходящего трафика.

Однако в такой системе неизбежно возникает следующий момент: пользователь может подряд быстро нажать на несколько ссылок «подробнее», в то время как сервер будет долго обрабатывать входящие запросы. Если в AJAX используется только один объект XMLHttpRequest (обычно так и есть), то все запросы свалятся в нем «в кучу», и результат запроса отобразится не там, где нужно. Таким образом, встает задача организовать очередь из однотипных асинхронных запросов к серверу, так, чтобы последующий выполнялся только после того, как закончится предыдущий.



Способ решения

Первый и самый очевидный способ — запретить в браузере саму асинхронность — выставить последний параметр ложным:
request.open(«GET», url, false);

К сожалению, хотя и верно, но срабатывает только в части браузеров, а, например, последний firefox 3.5 просто не выполняет такой запрос.

Второй вариант — завести массив из объектов XMLHttpRequest, и выполнять каждый запрос к серверу через свой объект. Неоптимально и неудобно.

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

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

Работающий пример скриптов можно посмотреть, например, вот здесь:
http://moiknigi.com/user_598/books/

Скрипты успешно работают в любых вариантах:
— открытие одного описания товара
— быстрое «прокликивание» нескольких товаров с дальнейшим ожиданием
— смешанный вариант: «кликание» на одни товары, в то время, когда открываются другие
— открытие полностью всех товаров одним кликом (в этом случае сразу образуется очередь из 20 элементов, которая затем постепенно очищается)

Выводы

Полагаю, подобный простой подход может использоваться на многих сайтах, отображающих различные однотипные списки (товаров, новостей и т.д.). Сами скрипты легки в понимании и занимают крайне малый объем.
Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
Total votes 11: ↑6 and ↓5+1
Comments11

Articles