до сих пор застряли на очередях?
ппц, не понимаю, как можно
попробую обьяснить, с самого начала.
у нас есть, к примеру, три функции.
function one () {
alert("Первая");
}
function two () {
alert("Вторая");
}
function three () {
alert("Третья");
}
есть такая фича - исполнение функций одна за другой.
если функции синхронные, то проблем нет - можно вызвать их одну за другой.
function one () {
alert("Первая");
}
function two () {
alert("Вторая");
}
function three () {
alert("Третья");
}
one();
two();
three();
ежели нет, то попытка вызвать их одну за другой, как обычно, не увенчается успехом :
function one () {
setTimeout(function () { alert("Первая"); }, 1000);
}
function two () {
setTimeout(function () { alert("Вторая"); }, 500);
}
function three () {
setTimeout(function () { alert("Третья"); }, 600);
}
one();
two();
three();
т.е. порядок будет нарушен. для этого вводят паттерн очередей.
function Queue () {
this.functions = [];
this.current = 0;
}
Queue.prototype.next = function () {
var func = this.functions.shift();
if (func) {
func.call(window, this);
}
};
Queue.prototype.add = function (func) {
this.functions.push(func);
};
Queue.prototype.launch = function () {
this.next();
};
с помощью него функция сама скажет, когда она закончила выполнение, и только после этого следующая на очереди функция начнёт выполняться.
"сказать", что она выполнилась, она сможет, вызвав метод
next своего первого аргумента.
перепишем чутка прошлый пример, чтобы он работал на очередях :
function Queue () {
this.functions = [];
this.current = 0;
}
Queue.prototype.next = function () {
var func = this.functions.shift();
if (func) {
func.call(window, this);
}
};
Queue.prototype.add = function (func) {
this.functions.push(func);
};
Queue.prototype.launch = function () {
this.next();
};
function one (queue) {
setTimeout(function () {
alert("Первая");
queue.next(); // закончила выполнение.
}, 1000);
}
function two (queue) {
setTimeout(function () { alert("Вторая"); queue.next(); }, 500);
}
function three (queue) {
setTimeout(function () { alert("Третья"); queue.next(); }, 600);
}
var myQueue = new Queue();
myQueue.add(one);
myQueue.add(two);
myQueue.add(three);
myQueue.launch();
замечательно - теперь они выполняются в строго определённом порядке - по порядку добавления (метод
add).
теперь перейдём от абстрактного примера к jQuery.
исходный код метода
queue :
<script src="http://code.jquery.com/jquery-1.8.1.js"></script>
<script>
document.write("<pre>" + $.queue + "</pre>");
</script>
и
dequeue :
<script src="http://code.jquery.com/jquery-1.8.1.js"></script>
<script>
document.write("<pre>" + $.dequeue + "</pre>");
</script>
детально обьяснять я их не буду, но скажу то, что мой код сверху, и их, очень похожи, за одним "НО" - у них поддерживаются несколько очередей, а у меня - одна.
теперь я добавлю в свою реализацию поддержку нескольких очередей, используя обёртку над прошлым скриптом :
function Queue () {
this.functions = [];
this.current = 0;
}
Queue.prototype.next = function () {
var func = this.functions.shift();
if (func) {
func.call(window, this);
}
};
Queue.prototype.add = function (func) {
this.functions.push(func);
};
Queue.prototype.launch = function () {
this.next();
};
function NamedQueue () {
this.queues = {};
}
NamedQueue.prototype.add = function (name, func) {
if (!this.queues[name]) {
this.queues[name] = new Queue();
}
this.queues[name].add(func);
};
NamedQueue.prototype.launch = function (name) {
this.queues[name].launch();
};
var myQueue = new NamedQueue();
myQueue.add("first", function (queue) { setTimeout(function () { alert("Первая функция, первая очередь."); queue.next(); }, 210); });
myQueue.add("second", function (queue) { setTimeout(function () { alert("Первая функция, вторая очередь."); queue.next(); }, 300); });
myQueue.add("first", function (queue) { setTimeout(function () { alert("Вторая функция, первая очередь."); queue.next(); }, 170); });
myQueue.add("second", function (queue) { setTimeout(function () { alert("Вторая функция, вторая очередь."); queue.next(); }, 240); });
myQueue.add("first", function (queue) { setTimeout(function () { alert("Третья функция, первая очередь."); queue.next(); }, 90); });
myQueue.add("second", function (queue) { setTimeout(function () { alert("Третья функция, вторая очередь."); queue.next(); }, 150); });
myQueue.launch("first");
myQueue.launch("second");
в jQuery - то же самое, только другими словами. Суть не меняется