jquery源码学习笔记(十六)

Posted 蓝度飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jquery源码学习笔记(十六)相关的知识,希望对你有一定的参考价值。

    首先,先把 then 的整体结构粘贴过来,这里只是为了定位我们将要分析的 resolve 方法,上次已经分析过 then 的结构和返回值。

    这里简单的简述一下 then 的主要用途,延迟函数若有获取数据失败等错误发生时,将直接报错,这将会导致后续函数没法继续执行。

    在 then 中,有针对状态的区分,在失败状态中,需要去执行 try catch,抛出异常,并执行 rejectWith 方法,来保证程序的稳定性。

then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function(){ // ...  }  } return jQuery.Deferred( function( newDefer ) { } ).promise();}

    接下来,我们来重点看看其中的 resolve 方法。

var maxDepth = 0;// 构建resovle函数,区分progress、reject、resovle三种状态// 进行中时,会传入 special=newDefer.notifyWithfunction resolve( depth, deferred, handler, special ) {  // 返回值是一个函数 return function() {    // 保存this指向 var that = this, args = arguments,      // 可能会抛出异常 mightThrow = function() {        var returned, then;        // then的返回值中三次调用传入的depth都为0        // maxDepth 在成功、失败的情况使,会在下面执行 maxDepth++        // 执行过++后,就会跳出mightThrow方法 if ( depth < maxDepth ) { return; }        // handler 分别可能是 进行中 成功 失败的回调函数        // 当进行中 成功的回调函数未传时,默认为Identity        // 当失败的回调函数未传时,默认为Thrower returned = handler.apply( that, args );        // 错误处理:抛出异常 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); }         // 当 returned 存在 且 returned 是对象或方法        // 将 returned.then 赋值给 then        then = returned && ( typeof returned === "object" || typeof returned === "function" ) && returned.then;
// then是一个函数        if ( isFunction( then ) ) { // 只有进行中 special 才会有值 if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special )            );          } else { // 成功、失败的情况下 没有传递 special            // 执行过后,以下的 resolve 中的 mightThrow 将会跳出            maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) );          }        } else {  // 当 then 不是一个方法时          // then 不存在,说明 returned 不是 deferred 对象 if ( handler !== Identity ) { that = undefined; args = [ returned ];          }          // 执行 fireWith ( special || deferred.resolveWith )( that, args ); } },       // special 存在就是 notify 调用      // 直接调用 mightThrow 即可 // 否则可能是 resolved 或 rejected,需要捕获异常 process = special ? mightThrow : function() { try { mightThrow();          } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace );            }            if ( depth + 1 >= maxDepth ) { if ( handler !== Thrower ) { that = undefined; args = [ e ];              } deferred.rejectWith( that, args ); } }        };     // 当depth不为 0,解决一下存在的异常 if ( depth ) { process();    } else { if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); }      // 异步执行 process window.setTimeout( process ); } };}

    由于我目前的能力所限,上述代码最后这块的 getStackHook 没什么了解,之后如果了解了,会再补充进来。

以上是关于jquery源码学习笔记(十六)的主要内容,如果未能解决你的问题,请参考以下文章

javascript 跟Aaron大神学习jquery源码笔记

jquery源码学习笔记(二十四)

Python学习笔记第二十六周(Django补充)

jQuery源码学习笔记

jQuery源码学习笔记

Ruby‘s Adventrue游戏制作笔记(十六)Unity子弹数量及其UI