Показать сообщение отдельно
  #2 (permalink)  
Старый 03.09.2012, 22:12
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

до сих пор застряли на очередях?

ппц, не понимаю, как можно

попробую обьяснить, с самого начала.

у нас есть, к примеру, три функции.
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 - то же самое, только другими словами. Суть не меняется

Последний раз редактировалось melky, 03.09.2012 в 22:14.
Ответить с цитированием