javascript代码实例教程-jQuery源码分析系列(38) : 队列操作

发布时间:2019-01-31 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-jQuery源码分析系列(38) : 队列操作脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 Queue队列,如同data数据缓存与Deferred异步模型一样,都是jQuery库的内部实现的基础设施

 

Queue队列是aniMATE动画依赖的基础设施,整个jquery中队列仅供给动画使用

 

 

 

Queue队列

 

队列是一种特殊的线性表,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队)。队列的特点是先进先出(FIFO-First in first out),即最先插入的元素最先被删除。

 

 

 

为什么要引入队列?

 

我们知道代码的执行流有异步与同步之分,例如

 

复制代码

VAR a = 1;

 

setTimeout(function(){

    a = 2;

},0)

 

alert(a) //1

复制代码

我们一直习惯于“线性”地编写代码逻辑,但是在JavaScript编程几乎总是伴随着异步操作

 

setTimeout,CSS3 TransITion/Animation,ajax,dom的绘制,postmessage,Web Database等等,大量异步操作所带来的回调函数,会把我们的算法分解地支离破碎

 

之前我们说过对于异步+回调的模式,怎么“拉平”异步操作,使之跟同步一样,因为异步操作进行流程控制的时候无非避免的要嵌套大量的回调逻辑,所以就会出现promises约定了

 

那么jQuery引入队列其实从一个角度上可以认为:允许一系列函数被异步地调用而不会阻塞程序

 

$("#Aaron").slideUp().fadein()

这是jQuery的一组动画链式序列,它的内部其实就是一组队列Queue,所以队列和Deferred地位类似, 是一个内部使用的基础设施,当slideUp运行时,fadeIn被放到fx队列中,当slideUp完成后,从队列中被取出运行。queue函数允许 直接操作这个链式调用的行为。同时,queue可以指定队列名称获得其他能力,而不局限于fx队列

 

 

 

jQuery提供了2组队列操作的API

 

jQuery.queue/dequeue

jQuery.fn.queue/dequeue

但是不同与普通队列定义的是:jQuery.queue和jQuery.fn.queue不仅执行出队操作,返回队头元素,还会自动执行返回的队头元素

 

fn是扩展在原型上的高级API是提供给实例使用的,.queue/.dequeue, 其内部是调用的.queue,.dequeue静态的底层方法实现入列与出列

 

 

 

$.queue : 显示或操作匹配的元素上已经执行的函数列队

 

这个方法有两个作用,它既是setter,又是getter。第一个参数elem是DOM元素,第二个参数tyPE是字符串,第三个参数data可以是function或数组

 

复制代码

var body = $('body');

function cb1() {alert(1)}

function cb2() {alert(2)}

 

//set

$.queue(body, 'aa', cb1); // 第三个参数为function

$.queue(body, 'aa', cb2); 

 

//get

$.queue(body, 'aa')  //[function ,function]

复制代码

这个方法有点类型get有点类似队列的push操作,jQuery的方法的接口重载是非常严重的,经常同一个接口即是set也是get,不管符不符合基本原则,但是它却很实用

 

无非就是把数据给缓存起来,为什么载体是一个jquery对象,因为保存数据的手段是通过data数据缓存实现的

 

data_PRiv = new Data();

复制代码

queue: function(elem, type, data) {

    var queue;

    if (elem) {

        type = (type || "fx") + "queue";

        queue = data_priv.get(elem, type);

        // Speed up dequeue by getting out quickly if this is just a lookup

        if (data) {

            if (!queue || jQuery.isArray(data)) {

                queue = data_priv.access(elem, type, jQuery.makeArray(data));

            } else {

                queue.push(data);

            }

        }

        return queue || [];

    }

},

复制代码

data与jQuery对象之间是通过uuid建立了一个无耦合的映射关系,具体可以翻阅之前的关于“数据缓存”

 

码有一个默认处理

 

type = (type || "fx") + "queue"

 

可见是专职供fx动画队列处理的

 

 

 

$.dequeue : 匹配的元素上执行队列中的下一个函数

 

复制代码

var body = $('body');

function cb1() {console.LOG(11111)}

function cb2() {console.log(22222)}

 

//set

$.queue(body, 'aa', cb1); // 第三个参数为function

$.queue(body, 'aa', cb2); 

 

 

$.dequeue(body, 'aa')  //11

$.dequeue(body, 'aa')  //22

复制代码

出列就有点类似shift的操作,但是不同的是还会执行这个cb1与cb2

 

将回调函数出列执行,每调用一次仅出列一个,因此当回调有N个时,需要调用$.dequeue方法N次元素才全部出列

 

来看看源码:

 

复制代码

var queue = jQuery.queue(elem, type),

    startLength = queue.length,

    fn = queue.shift(),

    hooks = jQuery._queueHooks(elem, type),

    next = function() {

        jQuery.dequeue(elem, type);

    };

复制代码

知道原理了, 这个就很简单了,通过queue的get取出队列的所有数据,判断一下长度,然后截取出第一个,然后做好一个预处理生成下一个的next

 

这里有一个hooks?

 

仔细分析下这个内部queueHooks

 

复制代码

_queueHooks: function(elem, type) {

    var key = type + "queueHooks";

    return data_priv.get(elem, key) || data_priv.access(elem, key, {

        empty: jQuery.Callbacks("once memory").add(function() {

            data_priv.remove(elem, [type + "queue", key]);

        })

    });

}

复制代码

我们说了dequeue不仅是取出来还需要执行,在执行的时候把next与hooks传递给外部的回调,

 

这就是js的逻辑上的很绕的地方,在内部可以传递一个引用出去,又能提供外部调用或者执行

 

fn.call(elem, next, hooks)

因为传递了next,所以我们的代码可以这样改

 

复制代码

var body = $('body');

function cb1(next,hoost) {

    console.log(11111)

    next()  //执行了cb2 //22222

}

 

function cb2() {

    console.log(22222)

}

 

//set

$.queue(body, 'aa', cb1); // 第三个参数为function

$.queue(body, 'aa', cb2); 

 

$.dequeue(body, 'aa')

复制代码

next内部仍然调用$.dequeue,这样可以接着执行队列中的下一个callback

 

$.dequeue里的hooks是当队列里所有的callback都执行完后(此时startLength为0)进行最后的一个清理工作

 

if ( !startLength && hooks ) {

    hooks.empty.fire();

}

钩子其实就是jQuery.Callbacks对象,可以实现一个收集器的功能,至于在什么情况下时候,之后动画中开始分析

 

 

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-jQuery源码分析系列(38) : 队列操作全部内容,希望文章能够帮你解决javascript代码实例教程-jQuery源码分析系列(38) : 队列操作所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。