deferred具有then done等属性。其区别在于Deferred resolved时,

  • done返回当前的的deferred object,callback的返回值不会被传递
  • then返回一个新的deferred object,callback的返回值会被传递(参考jquery的pipe属性)给新的callback
  • 通过以下的例子来理解下实际的运行效果。

    var defer = jQuery.Deferred();

    defer.done(function(a,b){
    console.log("a = " + a+"b = " + b);
    return a * b;

    }).done(function( result ) {
    console.log("result = " + result);

    }).then(function( a, b ) {
    console.log("a = " + a+"b = " + b);
    return a * b;

    }).done(function( result ) {
    console.log("result = " + result);

    }).then(function( a, b ) {
    console.log("a = " + a+"b = " + b);
    return a * b;

    }).done(function( result ) {
    console.log("result = " + result);
    });

    defer.resolve( 2, 3 );

    我任意找一个jsfiddle程序
    https://jsfiddle.net/founddrama/VxjZG/

    将上面的测试代码贴进js代码框中运行。
    输出结果是

    a = 2b = 3 (index):54
    result = 2 (index):58
    a = 2b = 3 (index):60
    result = 6 (index):63
    a = 6b = undefined (index):65
    result = NaN
  • 第一个done和第二个done都返回了defer.resolve( 2, 3 )
  • done中callback的返回值不会被传递
  • 第二个done只有一个参数,接收了defer.resolve( 2, 3 )的第一个参数2,所以result是2
  • 第一个then接收defer.resolve( 2, 3 ),接收两个参数,result是6,同时新建一个deferred object,传递result给deferred object
  • 第三个done接收到了这个新的deferred object和传递的result,打印结果是6,并把这个新的deferred object传递给第二个then
  • 第二个then现在接收新的deferred object,它只有一个参数,是result,所以参数b没有定义,返回的结果是NaN,同时又新建一个deferred object
  • 第四个done接收一个新建的deferred object,传递的参数是NaN,打印的结果自然就是NaN
  • http://stackoverflow.com/questions/5436327/jquery-deferreds-and-promises-then-vs-done(这里有done的更直观的示例)

    http://javascript.ruanyifeng.com/jquery/deferred.html