jQuery源码02--(3043 , 3183) Deferred : 延迟对象 : 对异步的统一管理
//延迟对象
jQuery.extend({ Deferred: function( func ) {
var tuples = [//resolve完成、reject未完成、notify进行中类似于fire,done、fail、progress回调函数的方法类似于add,jQuery.Callbacks()创建回调对象实现回调方法。映射数组。
// action, add listener, listener list, final state
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
[ "notify", "progress", jQuery.Callbacks("memory") ]
],
state = "pending",
promise = {
state: function() {
return state;
},
always: function() {
deferred.done( arguments ).fail( arguments );
return this;
},
then: function( /* fnDone, fnFail, fnProgress */ ) {
var fns = arguments;
return jQuery.Deferred(function( newDefer ) {
jQuery.each( tuples, function( i, tuple ) {
var action = tuple[ 0 ],//得到状态
fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];//是函数得到这个函数,不是函数返回假,
// deferred[ done | fail | progress ] for forwarding actions to newDefer
deferred[ tuple[1] ](function() {
var returned = fn && fn.apply( this, arguments );
if ( returned && jQuery.isFunction( returned.promise ) ) {
returned.promise()
.done( newDefer.resolve )
.fail( newDefer.reject )
.progress( newDefer.notify );
} else {
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
}
});
});
fns = null;
}).promise();
},
//jQuery.extend( obj, promise )这个promise是根据函数闭包,向上去找的,把promise复制给obj,
promise: function( obj ) {
return obj != null ? jQuery.extend( obj, promise ) : promise;
}
},
deferred = {}; // Keep pipe for back-compat
promise.pipe = promise.then; // 映射数组进行映射的函数
jQuery.each( tuples, function( i, tuple ) {
var list = tuple[ 2 ],//jQuery.Callbacks("once memory")
stateString = tuple[ 3 ];//resolved // promise[ done | fail | progress ] = list.add=jQuery.Callbacks("once memory").add方法
promise[ tuple[1] ] = list.add; // Handle state
if ( stateString ) {
list.add(function() {
// state = [ resolved | rejected ]
state = stateString; // [ reject_list | resolve_list ].disable; progress_list.lock
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
} // deferred[ resolve | reject | notify ]
deferred[ tuple[0] ] = function() {//给deferred这个json赋值
deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
return this;
};
// deferred[ resolveWith | rejectWith | notifyWith ]=jQuery.Callbacks("once memory").fireWith方法
deferred[ tuple[0] + "With" ] = list.fireWith;//继续给deferred这个json赋值
}); // 把promise复制给deferred,deferred比promise多了3个方法,
promise.promise( deferred ); // Call given func if any
if ( func ) {
func.call( deferred, deferred );
} // All done!
return deferred;
}, // Deferred helper
when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
resolveValues = core_slice.call( arguments ),
length = resolveValues.length, // 未完成函数的计数器,jQuery.isFunction( subordinate.promise ):subordinate的返回值是不是函数。
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values
updateFunc = function( i, contexts, values ) {
return function( value ) {
contexts[ i ] = this;
values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
if( values === progressValues ) {
deferred.notifyWith( contexts, values );
} else if ( !( --remaining ) ) {//减到0时触发resolveWith方法,
deferred.resolveWith( contexts, values );
}
};
}, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
resolveContexts = new Array( length );
for ( ; i < length; i++ ) {
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
resolveValues[ i ].promise()//返回值
.done( updateFunc( i, resolveContexts, resolveValues ) )//触发完成函数
.fail( deferred.reject )//触发失败函数
.progress( updateFunc( i, progressContexts, progressValues ) );
} else {
--remaining;
}
}
} //计时器为0时执行resolveWith方法,
if ( !remaining ) {
deferred.resolveWith( resolveContexts, resolveValues );
} return deferred.promise();//执行done方法,
}
});
jQuery源码02--(3043 , 3183) Deferred : 延迟对象 : 对异步的统一管理的更多相关文章
- 04 flask源码剖析之LocalStack和Local对象实现栈的管理
04 LocalStack和Local对象实现栈的管理 目录 04 LocalStack和Local对象实现栈的管理 1.源码入口 1. flask源码关于local的实现 2. flask源码关于l ...
- jQuery源码05 (3653 , 3797) queue() : 队列方法 : 执行顺序的管理
//对外接口 jQuery.extend({ queue: function( elem, type, data ) {//入队.元素.队列名字.存进去的函数 //jQuery.queue( this ...
- jQuery源码逐行分析学习02(第一部分:jQuery的一些变量和函数)
第一次尝试使用Office Word,方便程度大大超过网页在线编辑,不过初次使用,一些内容不甚熟悉,望各位大神见谅~ 在上次的文章中,把整个jQuery的结构进行了梳理,得到了整个jQuery的简化结 ...
- jQuery源码解析资源便签
最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...
- jQuery源码逐行分析学习01(jQuery的框架结构简化)
最近在学习jQuery源码,在此,特别做一个分享,把所涉及的内容都记录下来,其中有不妥之处还望大家指出,我会及时改正.望各位大神不吝赐教!同时,这也是我的第一篇前端技术博客,对博客编写还不是很熟悉,美 ...
- jQuery源码笔记(一):jQuery的整体结构
jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用 ...
- jquery源码分析(二)——架构设计
要学习一个库首先的理清它整体架构: 1.jQuery源码大致架构如下:(基于 jQuery 1.11 版本,共计8829行源码)(21,94) 定义了一些变量和函数jQu ...
- jQuery源码分析笔记
jquery-2.0.3.js版本源码分析 (function(){ (21,94) 定义了一些变量和函数 jQuery = function(){}; (96,283) 给JQ对象,添加一些方法 ...
- 读jQuery源码 - Callbacks
代码的本质突出顺序.有序这一概念,尤其在javascript——毕竟javascript是单线程引擎. javascript拥有函数式编程的特性,而又因为javascript单线程引擎,我们的函数总是 ...
随机推荐
- react ---- Router路由的使用和页面跳转
React-Router的中文文档可以参照如下链接: http://react-guide.github.io/react-router-cn/docs/Introduction.html 首先,我们 ...
- List<List<model>>如何更快捷的取里面的model?
访问接口返回数据类型为List<List<model>>,现在想将其中的model插入数据库,感觉一点点循环有点傻,0.0...,各位有没有其他的方法? List<Lis ...
- vue中指令写了一个demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- App开发Native.js入门指南
概述 Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术.如果说Node.js把js扩展到服务器世界,那么Native.js则把js扩展 ...
- Linux中常用命令(文件)
1.cat 显示出文件的全部内容 (1)格式:cat 文件名 -n 显示行号 (2)特点:一次性显示所有文件内容 2.tac 从最后一行倒着显示文件全部内容 3.more 全屏方式分页显示文件内容 回 ...
- awk 基础的用法
基本的awk执行过程#passwd文件的第二行的第一列和第二列[root@oldboyedu01-nb ~]# awk -F ":" 'NR==2{print $1,$2}' /e ...
- [APIO2009]会议中心(贪心)
P3626 [APIO2009]会议中心 题目描述 Siruseri 政府建造了一座新的会议中心.许多公司对租借会议中心的会堂很 感兴趣,他们希望能够在里面举行会议. 对于一个客户而言,仅当在开会时能 ...
- python中的类与继承
Class 类的定义以及实例的建立 Python中,类通过 class 关键字定义. 例如最简单的一个类定义可以为: class Person(object): pass Python 的编程习惯,类 ...
- cxf 实例解读
1.sample 实例之一---java_first_pojo 服务端发布服务的方法: 1 HelloWorldImpl helloworldImpl = new HelloWorldImpl(); ...
- [Python] Read and plot data from csv file
Install: pip install pandas pip install matplotlib # check out the doc from site import pandas as pd ...