文章出處

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>deferred對象</title>
    </head>
    <body>
        兩個對象,一個是promise對象,另一個是deferred對象。
        Deferred方法,返回deferred對象。
        Deferred里面有then方法,返回promise對象。
        
        
        jQuery源碼
        1.對參數做處理。
        處理的目的是,對不合法的參數,返回錯誤。
        對不同的參數類型,參數位置,做多態處理。
        2.常用&&或者||或者三目判斷。
        3.常用typeof做判斷。
        4.假設全部以正確方式來運行的態度,看代碼。
        5.剔除源代碼沒必要的遍歷,以最小集合來閱讀。
    </body>
    <script src="../jquery-2.0.3.js"></script>
    <script>
        /*
             dfd.then(fn1) 
            剛開始內部生成一個newDfd,
            先把fn1裝飾一下變成fn1-1,
            再把fn1-1給dfd的函數隊列。
            
            因為dfd內部的list是once memory了,
            所以fn1-1馬上執行,內容如下:
            fn1返回fn1-promise,
            然后把newDfd的resolve函數給fn1-promise。
            
            dfd.then(fn1)最后返回一個newDfd的newPromise
            因為fn1-deferred已經resolve過了,
            所以又執行newDfd.resolve,
            接下來是下一個then了。
         */
        //  看代碼,弄清空間和空間之間的運動關系,邏輯也就清晰了。 
        //  分主次,首先把分枝減掉,留下主干,把主干搞清楚。
        function Deferred( func ) {
            var list = jQuery.Callbacks("once memory");
            var promise = {
                then: function() {
                    var fns = arguments;
                    var newDfd = Deferred(function( newDefer ) {
                            var fn = jQuery.isFunction( fns[ 0 ] ) && fns[ 0 ];
                            deferred[ "done" ](function() {
                                var returned = fn && fn.apply( this, arguments );
                                returned.promise().done( newDefer.resolve )
                            });
                        fns = null;
                    });
                    var newPromise = newDfd.promise();
                    return newPromise;
                },
                promise: function( obj ) {
                    return obj != null ? jQuery.extend( obj, promise ) : promise;
                },
                done: list.add
            },
            deferred = {
                resolve: function() {
                    deferred[ "resolveWith" ]( this === deferred ? promise : this, arguments );
                    return this;
                },
                resolveWith: list.fireWith,
                flag:"newDfd"
            };


            promise.promise( deferred );
    
            if ( func ) {
                func.call( deferred, deferred );
            }
    
            return deferred;
        }
        
        var dfd = Deferred();
        dfd.flag = "dfdflag";
        dfd.then(function(){
            var dfd1 = Deferred();
            dfd1.flag = "dfd1flag";
            alert(1);
            dfd1.resolve();
            
            return dfd1.promise();
        }).then(function(){
            var dfd2 = Deferred();
            alert(2);
            dfd2.resolve();
            return dfd2.promise();
        }).then(function(){
            var dfd3 = Deferred();
            alert(3);
            dfd2.resolve();
            return dfd2.promise();
        });
        
        dfd.resolve();
        
        
    </script>
    
</html>

 其實jQuery的Deferred還是有bug的。

設想如下代碼:

function(){
    var dfd = $.Deferred();
    dfd.resolve();
    $.ajax()

    return dfd.promise();
}

就算你提前resolve,ajax還是會執行。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()