05异步队列 Deferred 使用介绍(3)


// Deferred helper
// 异步队列工具函数
// firstParam:一个或多个Deferred对象或JavaScript普通对象
when: function( firstParam ) {
var args = arguments,
i = 0,
length = args.length,
count = length,
// 如果arguments.length等于1,并且firstParam是Deferred,则deferred=firstParam
// 否则创建一个新的Deferred对象(如果arguments.length等于0或大于1,则创建一个新的Deferred对象)
// 通过jQuery.isFunction( firstParam.promise )简单的判断是否是Deferred对象
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
firstParam :
jQuery.Deferred();
// 构造成功(resolve)回调函数
function resolveFunc( i ) {
return function( value ) {
// 如果传入的参数大于一个,则将传入的参数转换为真正的数组(arguments没有slice方法,借鸡生蛋)
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
if ( !( --count ) ) {
// Strange bug in FF4:
// Values changed onto the arguments object sometimes end up as undefined values
// outside the $.when method. Cloning the object into a fresh array solves the issue
// 执行成功回调函数队列,上下文强制为传入的第一个Deferred对象
deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
}
};
}
// 如果参数多于一个
if ( length > 1 ) {
for( ; i < length; i++ ) {
// 简单的判断是否是Deferred对象,是则调用.promise().then(),否则忽略
if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
// 增加成功回调函数和失败回调函数到各自的队列中
args[ i ].promise().then( resolveFunc(i), deferred.reject );
} else {
// 计数器,表示发现不是Deferred对象,而是普通JavaScript对象
--count;
}
}
// 计数器为0时,表示传入的参数都不是Deferred对象
// 执行成功回调函数队列,上下文强制为传入的第一个Deferred对象
if ( !count ) {
deferred.resolveWith( deferred, args );
}
// deferred !== firstParam,即deferred为新创建的Deferred对象
// 即length == 0
} else if ( deferred !== firstParam ) {
// 执行成功回调函数队列,上下文强制为新创建的Deferred对象
deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
}
// 返回传入的第一个Deferred或新创建的Deferred对象的只读视图
return deferred.promise();
}



5.6 Deferred应用
l jQuery.ajax()
n TODO
5.7 可以学习的技巧
l 闭包

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdjfjf.html