章节
问答
笔记
评论
占位
占位

回调的灵活运用

我们经常会这样使用函数回调:

     事件触发通知

     资源加载通知

     定时器延时

     ajax、动画通知等等。

以上都是很单一的事件监听回调的处理方式,但是jQuery把回调函数的用法设计成一个更高的抽像,用于解耦与分离变化。

如何理解这个设计?我们看下面的例子。

例子一:

jQuery针对Dom的处理提供了append、prepend、before、after等方法的处理,这几个方法的特征:

1、参数的传递可以是HTML字符串、DOM元素、元素数组或者jQuery对象

2、为了优化性能针对节点的处理需要生成文档碎片

可见几个方法都是需要实现这2个特性的,那么我们应该如何处理?

高层接口:

before: function() {
    return this.domManip(arguments, function(elem) {
        if (this.parentNode) {
            this.parentNode.insertBefore(elem, this);
        }
    });
},

after: function() {
    return this.domManip(arguments, function(elem) {
        if (this.parentNode) {
            this.parentNode.insertBefore(elem, this.nextSibling);
        }
    });
},

底层实现:

domManip: function(args, callback) {
    // Flatten any nested arrays
    args = concat.apply([], args);
    // We can't cloneNode fragments that contain checked, in WebKit
    if (isFunction ||
        //多参数处理
        self.domManip(args, callback);
    }

    if (l) {
        //生成文档碎片
        fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, this);
        callback.call(this[i], node, i);
    }
    return this;
}

我们观察下jQuery的实现,通过抽象出一个domManip方法,然后在这个方法中处理共性,合并多个参数的处理与生成文档碎片的处理,然后最终把结果通过回调函数返回给每一个调用者。

例子二:

在很多时候需要控制一系列的函数顺序执行。那么一般就需要一个队列函数来处理这个问题。

我们看一段代码:

function Aaron(List, callback) {
    setTimeout(function() {
        var task;
        if (task = List.shift()) {
            task(); //执行函数
        }
        if (List.length > 0) { //递归分解
            arguments.callee(List)
        } else {
            callback()
        }
    }, 25)
}

//调用
​Aaron([
    function() {
        alert('a')
    },
    function() {
        alert('b')
    },
    function() {
        alert('c')
    }
], function() {
    alert('callback')
})

// 分别弹出 ‘a’ , ‘b’ ,'c',’callback

传入一组函数参数,靠递归解析,分个执行,其实就是靠setTimeout可以把函数加入到队列末尾才执行的原理,这样的写法就有点就事论事了,聚合对象完全是一个整体,无法再次细分出来,所以我们需要一种方案,用来管理分离每一个独立的对象。

我们换成jQuery提供的方式:

var callbacks = $.Callbacks();
callbacks.add(function() {
    alert('a');
})
callbacks.add(function() {
    alert('b');
})
callbacks.fire(); //输出结果: 'a' 'b'

是不是便捷很多了,代码又很清晰,所以Callbacks它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。

那么我们使用回调函数,总的来说弱化耦合,让调用者与被调用者分开,调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件的被调用函数。

 

任务

?不会了怎么办
||

提问题

写笔记

截图
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最新 点赞
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?