jquery中的 deferred之 deferred对象

Posted huaan011

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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对象 的主要内容,如果未能解决你的问题,请参考以下文章

deferred 对象

deferred对象和promise对象

jquery中的 deferred之 deferred对象

如何使Doctrine PostgreSQL外键约束DEFERRABLE

jQuery 源码解析 异步队列模块 Callbacks 回调函数详解

jQuery之Deferred源码剖析