jQuery->Deferred then

 

合格的项目经理应该具备哪些技能?

奥,不知道哎!但我知道不合格的项目经理具备哪些特点

1. 不懂代码

2. 不懂代码

3. 还是不懂代码

 

1. then返回值是什么?var a = aDeferred.then(),a和aDeferred是什么关系?

then的返回值是一个promise,也就是没有触发功能(resolve,reject,notify)的Deferred对象
a和aDeferred啥关系也不是,a是新生成的promise。

 

2. $.Deferred(fn)是什么意思?

$.Deferred(fn)等价于:
var t = $.Deferred(); fn.call(t , t);
即在t的作用域上,函数fn以t为参数做调用。

 

3. var t = $.Deferred().then(); t和下面代码中then函数中的newDefer参数是什么关系?

newDefer中的属性copy自t,t是newDefer的子集

then: function() {

    var fns = arguments;

    return jQuery.Deferred(function( newDefer ) {...

    }).promise();

}	



4 tuples来自哪里?deferred指的是谁?

假设调用t.then(),tuples是生成t时产生的,deferred同理

    then: function( /* fnDone, fnFail, fnProgress */ ) {

        var fns = arguments;

        return jQuery.Deferred(function( newDefer ) {

            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 );

                    if ( returned && jQuery.isFunction( returned.promise ) ) {

                        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();

    }

 


5.$.each(arr, fn);函数fn中的this对象是谁?

arr[i],$.each中对fn的调用进行了作用域的绑定

each: function( obj, callback, args ) {

    ... 

    } else {

         if ( isArray ) {

             for ( ; i < length; i++ ) {

                 value = callback.call( obj[ i ], i, obj[ i ] );

                 ...

             }

        }

    }

    return obj;

}


6. deferred[ tuple[1] ](fn)在做什么?

将fn添加到deferred的回调函数列表,以便deferred.resolve/reject()触发后回调fn



7. jQuery.isFunction( returned.promise )是什么意思?

判断returned是否至少是promise对象。



8. returned.promise().done( newDefer.resolve )在做什么?

为returned添加处理完成的回调函数,以便returned.resolve()后去执行newDefer.resolve()



9 fn是函数,
jQuery.isFunction( fn().promise ) === false;
$.Deferred().done(fn)与$.Deferred().then(fn)有何区别?

$.Deferred().then(fn)缺少回调函数绑定时,两者没有区别,后者会在结束时触发新生成的Deferred对象的resolveWith方法。



10 then 和pipe的区别

jquery早期版本中pipe的功能和目前(jquery1.10.1)then的功能是一致的,目前pipe是then的别名,考虑向后兼容



11.then的实际用途[1]

上面的情况下,done和then方式的调用几乎没有区别
看看下面这种情况,ajax请求,返回的数据用于修改页面的值。

$.ajax("your/url", {

    dataType: "json"

}).done(

    function(data) {

        $.each(data, function(key, value) {

    $("#" + key).val(value);

    });

});

现在假设value并不是最终要展示的值,需要对value进行转换,value = doSomethingWith(value);如果doSomethingWith包含了异步操作,怎么确保异步操作之后将正确的结果显示出来呢?

这个时候就用到了then,第一个ajax,称作ajax1,响应完成后,流程转到了then,then中返回ajax(延迟对象) ajax2,最终,ajax2调用完成触发resolve执行done添加的函数队列,将结果显示出来。

 

    $.ajax("your/url", {

        dataType: "json"

    }).then(function(theOriginalData) {

        return $.ajax("your/web/service/doSomethingWith", {

            data: theOriginalData,

            dataType: "json"

        });

    }).done(function(theFinalData) {

        $.each(theFinalData, function(key, value) {

            $("#" + key).val(value);

        });

    });

 

 

12 异步操作之间数据是如何传递?

以上面的示例说明,ajax1处理成功之后,会调用resolveWith触发回调函数队列

  deferred.resolveWith( callbackContext, [ theOriginalData, statusText, jqXHR ] );->

    

  (function() {

        var returned = fn && fn.apply( this, arguments );

        if ( returned && jQuery.isFunction( returned.promise ) ) {

            returned.promise()

                .done( newDefer.resolve )

                .fail( newDefer.reject )

                .progress( newDefer.notify );

        } else {

            newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );

        }

    }).apply(callbackContext, [ theOriginalData, statusText, jqXHR ]); ->

    

    fn.apply( this, arguments )-> //触发另一个

    

    (function(theOriginalData) {

        return $.ajax("your/web/service/doSomethingWith", {

            data: theOriginalData,

            dataType: "json"

        });

    }).apply(callbackContext, [ theOriginalData, statusText, jqXHR ]);->

    

    $.ajax("your/web/service/doSomethingWith", {

            data: theOriginalData,

            dataType: "json"

    }); -> //异步操作完成后

    

    deferred.resolveWith( callbackContext, [ theFinalData, statusText, jqXHR ] );->

    

    newDefer.resolve( callbackContext, [ theFinalData, statusText, jqXHR ] ); ->

    

    (function(theFinalData) {

        $.each(theFinalData, function(key, value) {

            $("#" + key).val(value);

        });

    }).apply( callbackContext, [ theFinalData, statusText, jqXHR ] ); 

 


 

 

[1]代码来源:understanding-deferred-pipe 

[2]函数上下文中确定this的值的规则

this的值由调用者提供,由调用函数的方式决定,如果调用括号()左边是引用类型,this为这个引用类型值的base对象,其他情况this为全局对象

function foo() {

    console.log(this);

}



foo(); // global, because



var fooReference = {

    base: global,

    propertyName: 'foo'

};



// 另一种调用形式

foo.prototype.constructor(); //foo.prototype, because



var fooPrototypeConstructorReference = {

    base: foo.prototype,

    propertyName: 'constructor'

};



思考下面函数表达式:

(function() {

    console.log(this); // null => global

})();



function foo() {// 解释 http://dmitrysoshnikov.com/ecmascript/chapter-3-this/#comment-342

    function bar() {

        console.log(this); // => global

    }

    bar();

}

 [3]源码1.10.1

 

你可能感兴趣的:(deferred)