Важным инструментом для контроля последовательности исполнения функций в асинхронной среде являются очереди. Об одной из реализаций я писал в заметке «Очередь: синхронное выполнение функций».
В jQuery тоже есть механизм, реализующий очередь — это функции queue и dequeue.
Каждая именованная очередь прикрепляется к DOM элементу, который и будет контекстом выполнения функций. К одному элементу может быть прикреплено сколько угодно очередей. Важно лишь, чтобы они имели различные имена.
Рассмотрим пример:
$("#result")
.queue("test", function () {
$(this)
.append("<p>1st function</p>")
.queue("test", function () {
$(this)
.append("<p>4th function</p>")
.dequeue("test");
})
.dequeue("test");
})
.queue("test", function () {
$(this)
.append("<p>2nd function</p>")
.dequeue("test");
})
.queue("test", function () {
$(this)
.append("<p>3rd function. " +
$(this).queue("test").length +
" function(s) in queue</p>")
.queue("test", function () {
$(this)
.append("<p>5th function</p>")
.dequeue("test");
})
.dequeue("test");
})
.dequeue("test");
В нем я к элементу прикрепляю очередь из 3-х функций, затем в процессе выполнения этих функций в очередь добавляются еще 2.
Результатом работы этого кода будет:
1st function
2nd function
3rd function. 1 function(s) in queue
4th function
5th function
В третьей по счету функции выводится количество оставшихся функций в очереди. На момент исполнения там остается только одна функция (4-ая по счету), но сразу после этого добавляется еще и 5-ая.
Каждая функция по своему завершению должна вызвать метод dequeue, чтобы передать управление следующей функции в очереди.
Коментарии к заметке
Владимир, пожалуйста, объясните почему функция добавляемая во время выполнения первой, становится четвертой?! Почему не второй? Я чего-то тут глобально не понимаю :( Получается, что в момент выполнения первой функции, очередь до третьей уже существует?
Да, именно так.
Тут всё просто.
queue()
только добавляет функцию в очередь. Выполняться функции начнут после вызоваdequeue()
. Таким образом, в очередь складываются первые три функции, а потом туда добавляются другие.Обрати внимание на то, что функций в очереди всегда выполняются асинхронно. Когда функция завершается, то это не значит, что начнёт выполняться следующая. Нужно явно вызвать
dequeue()
, чтобы продолжить обработку очереди.Ох и непростые эти очереди. Ну ничего, еще 100 статей прочитаю и разберусь ))))))))