首页 > 代码库 > jquery中的 deferred之 deferred对象 (一)

jquery中的 deferred之 deferred对象 (一)

案例:

var def=$.Deferred();console.log(def);//答案见 图1

 图1:技术分享

deferred就是一个有这些方法的对象。

看源码分析:

Deferred: function( func ) {        var tuples = [                // 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) { //20170620 huanhua 当调用 jQuery.Deferred(参数)  参数不为空的时候,参数必须是 包含 $.Deferred()对象参数的函数                                                                  //if ( func ) { func.call( deferred, deferred );} 详见下面这段代码。                        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);                                //20170620 huanhua 如果then方法传递的参数 [fnDone, fnFail, fnProgress],其中的函数如果返回的是 Defferred对象。                                if (returned && jQuery.isFunction(returned.promise)) {                                    //20170620 huanhua 此时注册的 done/fail/progess 就是传入的 Defferred对象已经注册好了的对象                                    //20170624 huahua returned是一个 deferred,在 fn 里面,必须要调用 deferred.resolve/deferred.reject/deferred.notify                                    //否则不会 触发 newDefer.resolve/newDefer.reject/newDefer.notify                                    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();                },                // Get a promise for this deferred                // If obj is provided, the promise aspect is added to the object                promise: function (obj) {                    return obj != null ? jQuery.extend( obj, promise ) : promise;                }            },            deferred = {};        // Keep pipe for back-compat        promise.pipe = promise.then;        // Add list-specific methods        jQuery.each( tuples, function( i, tuple ) {            var list = tuple[2], //20170619 huanhua jQuery.Callbacks("once memory") | jQuery.Callbacks("once memory") | jQuery.Callbacks("memory")                stateString = tuple[3]; //20170619 huanhua "resolved" | "rejected" | undefined            // promise[ done | fail | progress ] = list.add            //20170619 huanhua  promise.done/promise.fail/promise.progess = jQuery.Callbacks(参数).add            promise[ tuple[1] ] = list.add;            // Handle state            //20170619 huanhua stateString取值 "resolved" | "rejected" | undefined            if ( stateString ) {                list.add(function() {                    // state = [ resolved | rejected ]                    state = stateString;                    // [ reject_list | resolve_list ].disable; progress_list.lock                    //20170619 huanhua 0 ^ 1=1  1 ^ 1 = 0  2 ^ 1 = 3                    //20170619 huanhua stateString取值 "resolved" | "rejected" | undefined,所以 i 只能取值 0或者 1                    //20170620 huanhua 解释 tuples[i ^ 1][2].disable, tuples[2][2].lock                    //当 i=0 时,stateString="resolved",已经执行完,tuples[i ^ 1][2]=tuples[1][2],就是 fail的 disable,tuples[2][2] 就是 progess的 lock                    //当 i=1 时,stateString="rejected",已经拒绝了,tuples[i ^ 1][2]=tuples[0][2],就是 done的 disable,tuples[2][2] 就是 progess的 lock                }, tuples[i ^ 1][2].disable, tuples[2][2].lock);            }            // deferred[ resolve | reject | notify ]            //20170619 huanhua deferred.resolve()/deferred.reject()/deferred.notify()            //最终调用的都是  deferred.resolveWith()/deferred.rejectWith()/deferred.notifyWith()            deferred[tuple[0]] = function () {                deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);                return this;            };            //20170619 huanhua deferred.resolveWith()/deferred.rejectWith()/deferred.notifyWith()最终调用的就是 callBacks的 fire()            deferred[ tuple[0] + "With" ] = list.fireWith;        });        // Make the deferred a promise        // 20170619 huanhua 把promise的属性全部扩展到 defferred对象上        promise.promise( deferred );        // Call given func if any        if ( func ) {            func.call( deferred, deferred );        }        // All done!        return deferred;    },

 

jquery中的 deferred之 deferred对象 (一)