js-jQuery中的Callbacks、Deferred和When对象详解(2)
来源:互联网 发布:知善恶树 编辑:程序博客网 时间:2024/06/06 00:29
上次只讲到了Deferred的如何组装对应方法和Promise的组成部分,并没有将Deferred的真正核心代码讲解了。今天抽出时间来讲解一下,不废话,直接看then方法:
then: function( /* fnDone, fnFail, fnProgress */ ) {var fns = arguments;return jQuery.Deferred(function( newDefer ) {jQuery.each( tuples, function( i, tuple ) {var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];// deferred[ done | fail | progress ] for forwarding actions to newDeferdeferred[ 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[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );}});});fns = null;}).promise();}
then方法绝对是jQuery中高质量的代码了。
先讲下这段代码的设计思路:then方法每次返回一个新Deferred对象的promise对象,在创建新Deferred对象时指定了一个回调函数,新Deferred对象作为参数传到该回调函数中来。在这段回调函数中:给上一个(即旧的)Deferred对象的done|fail|progress的回调列表中添加函数——该函数会调用then的传入参数的函数,同时判断该函数的返回值,如果是一个promise对象则将新Deferred对象的调用加入到该promise的回调列表中(也就是会在该promise对象notify|resolve|reject时进行调用),否则调用新的Deferred对象的回调列表并将返回值returned作为参数传递。
再说得简单点就是:每次调用then方法会返回产生新的deferred对象,同时then指定的参数会添加到旧的deferred的回调列表中,进行链式调用then方法时,会产生多个deferred对象,每个deferred对象的闭包中含有上个(即旧的)deferred对象——该对象将then指定的参数添加到回调列表中。最后通过一个的方法把所有对象的操作都串联起来,所有的函数操作就可以一个接着一个的执行了。
then方法的核心思想就是:通过将新对象的notify|resolve|reject方法添加到旧对象对应的progress|done|fail中去,将所有对象的操作串联起来。每次then方法产生的新对象将保存自身的状态。
以上就是then方法也就是Deferred的管道流了。
再看when方法:
// Deferred helperwhen: function( subordinate /* , ..., subordinateN */ ) {var i = 0,resolveValues = slice.call( arguments ),length = resolveValues.length,// the count of uncompleted subordinatesremaining = 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 valuesupdateFunc = function( i, contexts, values ) {return function( value ) {contexts[ i ] = this;values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;if ( values === progressValues ) {deferred.notifyWith( contexts, values );} else if ( !(--remaining) ) {deferred.resolveWith( contexts, values );}};},progressValues, progressContexts, resolveContexts;// add listeners to Deferred subordinates; treat others as resolvedif ( 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;}}}// if we're not waiting on anything, resolve the masterif ( !remaining ) {deferred.resolveWith( resolveContexts, resolveValues );}return deferred.promise();}相对来说when方法看起来要直观的多,用起来也算简单,when方法常用于合并多个异步操作。
通过给resolveValues的promise添加对应的done|fail|progress回调列表中添加updateFunc方法去改变remaining数量,如果remaining为0时则调用主deferred对象的resolveWith触发自己绑定的异步操作全部执行完毕后的函数操作,如果失败则触发主deferred对象的reject,同样触发自己绑定的失败函数操作。
相对来说when方法要简单、直观得多,也比较好理解。也算我偷个懒,when方法就讲到这里。
有其他疑问或错误之处欢迎之处~
允许转载,但请带上出处:http://blog.csdn.net/z905951024 by denied.
以上。
- js-jQuery中的Callbacks、Deferred和When对象详解(2)
- js-jQuery中的Callbacks、Deferred和When对象详解(1)
- jquery中的工具方法--Deferred和when
- 详解Jquery deferred 对象
- jquery中的deferred详解
- jquery的when和Deferred方法
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- jQuery的deferred对象详解
- 黑马程序员——Java基础---集合
- POJ 2785: four values sum is zero
- 时间的自然哲学
- iOS id类型的方法调用
- 抽象工厂模式
- js-jQuery中的Callbacks、Deferred和When对象详解(2)
- JAVA基础学习笔记(1)
- 在delphi中实现密码框“大写锁定打开”的提示
- python学习笔记1.import
- eclipse的常用快捷键
- C++——构造和析构函数
- sgu 171
- VB.NET视频小结
- 最全最常用的期货技术指标三十个