jQuery源码学习:异步操作--Callbacks

栏目: jQuery · 发布时间: 6年前

内容简介:jQuery封装了很多关于异步操作的方法,比如$.Callbacks()返回一个Callbacks对象,你可以调用该对象的方法对函数列表进行操作,要实现这样的功能很简单,下面是一个简易的实现同样的功能,只不过jQuery支持了不同的调用方式

jQuery封装了很多关于异步操作的方法,比如 $.ajax $.Deferred 等等,这些方法都是以Callbacks为基础开发的,Callbacks一个多用途的回调列表对象,提供了强大的的方式来管理回调函数列表,他可以管理一个列表,在你需要执行时候触发,触发时机由调用fire方法决定

了解API

var cb = $.Callbacks();
cb.add(function(){
    console.log('first function');
})
cb.add(function () {
    console.log('second function');
})
cb.fire();
// first function
// second function
复制代码

$.Callbacks()返回一个Callbacks对象,你可以调用该对象的方法对函数列表进行操作,要实现这样的功能很简单,下面是一个简易的实现

function Callbakcs () {
    var list = []
    return {
        add: function (func) {
            list.push(func);
        },
        fire: function () {
            var args = [].slice.call(arguments);
            list.forEach(function(item) {
                item.apply(null, arguments);
            })
        }
    }
}
复制代码

同样的功能,只不过jQuery支持了不同的调用方式

参数

在调用$.Callbacks的时候,我们可以传入一个参数用来改变回调列表的行为

  • once 确保改列表只执行一次,调用fire过后便失效
  • unique 一个回调只会被添加一次,不会重复添加
  • stopOnFalse 在某一个回调返回false时候立即停止执行后面函数
  • memory 缓存上一次fire的参数,下一次add的时候执行用上一次的参数调用
// 支持两种传参方式,一种对象类的,一种字符串类的,可组合使用,传入字符串的时候会对字符串进行处理转换为对象
var cb = $.Callback("once unique");

var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );

function createOptions( options ) {
	var object = {};
	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
		object[ flag ] = true;
	} );
	return object;
}

// 函数内部存储了一个options对象,最后会是类似{once: true, unique: true}这样的对象

复制代码

变量说明

在函数内部我们还能看到其他一些变量

var //  标记是否正在触发
	firing,

	//  缓存的上一次调用时候的参数和this指向
	memory,

	// 标记是否已经调用过fire
	fired,

	// 防止调用的标记
	locked,

	// 回调列表
	list = [],

	// 参数和this指向的列表
	queue = [],

	// 标记当前执行到哪个回调
	firingIndex = -1,
	
	// 执行回调列表 
	fire = function () {}
	
	// 暴露的对象
	self = {}
复制代码

add

add方法主要会判断是否是unique、memory模式、unique遇到相同的回调函数回过滤掉,memory会检查fired是否为true,如果是会将memory里面的参数添加到queue队列中,最后调用fire

if ( memory && !firing ) {
    	firingIndex = list.length - 1;
    	queue.push( memory );
	}
	if ( memory && !firing ) {
    	firingIndex = list.length - 1;
    	queue.push( memory );
	}

	( function add( args ) {
    	jQuery.each( args, function( _, arg ) {
    		if ( isFunction( arg ) ) {
    			if ( !options.unique || !self.has( arg ) ) {
    				list.push( arg );
    			}
    		} else if ( arg && arg.length && toType( arg ) !== "string" ) {
    
    			// Inspect recursively
    			add( arg );
    		}
    	} );
	} )( arguments );

复制代码

添加的是否用到了递归,因为支持了传入数组的方法

fire

self里面会调用fireWith方法,我们在调用fire的时候实际上是调用的这个方法

fire: function() {
	self.fireWith( this, arguments );
	return this;
},
fireWith: function( context, args ) {
    if ( !locked ) {
    	args = args || [];
    	args = [ context, args.slice ? args.slice() : args ];
    	// 降参数和this对象缓存到queue里面
    	queue.push( args );
    	if ( !firing ) {
    		fire();
    	}
    }
    return this;
},
复制代码

真正的fire会遍历取出queue里面的参数,缓存到memory里面,如果不是memory模式则会在后面清除掉,遍历list,用memory里的参数调用各个方法

for ( ; queue.length; firingIndex = -1 ) {
	memory = queue.shift();
	while ( ++firingIndex < list.length ) {

    // 如果传入stopOnFalse,且返回false,立即停止遍历
    if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
    	options.stopOnFalse ) {
    	firingIndex = list.length;
    	memory = false;
    }
	}
}
复制代码

Callback部分的代码比较简单,当然这部分都是同步逻辑,callback是Deffered的基础,所以需要先明白一下原理


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据挖掘十大算法

数据挖掘十大算法

(美)吴信东(Xindong Wu)、(美),库玛尔 ,(Vipin Kumar) / 李文波、吴素研 / 清华大学出版社 / 2013-5 / 39.00元

《世界著名计算机教材精选:数据挖掘十大算法》详细介绍了在实际中用途最广、影响最大的十种数据挖掘算法,这十种算法是数据挖掘领域的顶级专家进行投票筛选的,覆盖了分类、聚类、统计学习、关联分析和链接分析等重要的数据挖掘研究和发展主题。《世界著名计算机教材精选:数据挖掘十大算法》对每一种算法都进行了多个角度的深入剖析,包括算法历史、算法过程、算法特性、软件实现、前沿发展等,此外,在每章最后还给出了丰富的习......一起来看看 《数据挖掘十大算法》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码