队列是一种特殊的线性表,是一种先进先出的机制,把其想象成排队的场景即可。
jQuery中队列入队
queue: function(elem, type, data) {
var queue;
if (elem) {
type = (type || 'fx') + 'queue';
queue = dataPriv.get(elem, type);
// Speed up dequeue by getting out quickly if this is just a lookup
if (data) {
if (!queue || Array.isArray(data)) {
queue = dataPriv.access(
elem,
type,
jQuery.makeArray(data)
);
} else {
queue.push(data);
}
}
return queue || [];
}
},
入队的时候会判断queue是否存在,若是第一次入队,会把对应的回调函数存储在元素上,作为缓存,下次进来的时候只需要简单的push操作即可(queue.push)。说白了就是data与jQuery之间通过了uuid建立了一个无耦合的映射关系,这就涉及到之前文章cache的知识了。
jQuery队列出队
dequeue: function(elem, type) {
type = type || 'fx';
var queue = jQuery.queue(elem, type),
startLength = queue.length,
fn = queue.shift(),
hooks = jQuery._queueHooks(elem, type),
next = function() {
jQuery.dequeue(elem, type);
};
// If the fx queue is dequeued, always remove the progress sentinel
if (fn === 'inprogress') {
fn = queue.shift();
startLength--;
}
if (fn) {
// Add a progress sentinel to prevent the fx queue from being
// automatically dequeued
if (type === 'fx') {
queue.unshift('inprogress');
}
// Clear up the last queue stop function
delete hooks.stop;
fn.call(elem, next, hooks);
}
if (!startLength && hooks) {
hooks.empty.fire();
}
},
_queueHooks: function(elem, type) {
var key = type + 'queueHooks';
return (
dataPriv.get(elem, key) ||
dataPriv.access(elem, key, {
empty: jQuery.Callbacks('once memory').add(function() {
dataPriv.remove(elem, [type + 'queue', key]);
})
})
);
}
从上面的源码可以看出,jQuery.queue既可以用来存储缓存数据,还可以用来获取队列数据,通过queue.shift(),来获取一个回调函数, fn.call(elem, next, hooks)来执行回调函数,并且把next,hooks,传递给外面使用,其中next是下个队列中下一个子项(fn)要执行的函数,hooks是callbacks相关函数。
jQuery队列的源码其实很少,也比较好分析。