jQuery的Deferred

<!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还是会执行。

原文地址:https://www.cnblogs.com/samwu/p/4300394.html