我一直在阅读jQuery的延迟和承诺,我看不出使用.then()和.done()成功回调之间的区别。我知道Eric Hynds提到.done()和.success()映射到相同的功能,但我猜.then()也是如此,因为所有的回调都是在成功操作完成时调用的。

有人能告诉我正确的用法吗?


当前回答

.done()终止承诺链,确保没有其他步骤可以附加。这意味着jQuery承诺实现可以抛出任何未处理的异常,因为没有人可以使用.fail()处理它。

实际上,如果您不打算为承诺附加更多步骤,则应该使用.done()。要了解更多细节,请参阅为什么需要兑现承诺

其他回答

Then()总是意味着在任何情况下都会调用它。但是在不同的jQuery版本中传递的参数是不同的。

在jQuery 1.8之前,then()等于done().fail()。所有的回调函数共享相同的参数。

但是从jQuery 1.8开始,then()返回一个新的promise,如果它有返回值,它将被传递到下一个回调函数。

让我们看看下面的例子:

var defer = jQuery.Deferred();

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

defer.resolve( 3, 4 );

在jQuery 1.8之前,答案应该是

result = 3
result = 3
result = 3

所有结果花费3。然后()函数总是将相同的延迟对象传递给下一个函数。

但是从jQuery 1.8开始,结果应该是:

result = 3
result = 7
result = NaN

因为第一个then()函数返回一个新的promise,值7(这是唯一要传递的参数)被传递给下一个done(),所以第二个done()将result = 7。第二个then()将7作为a的值,并将undefined作为b的值,因此第二个then()返回一个带有参数NaN的新承诺,最后一个done()打印NaN作为其结果。

.done()只有一个回调,它是成功回调

.then()有success和fail两个回调函数

.fail()只有一个失败回调

所以你该怎么做就怎么做了…你在乎成功还是失败吗?

附加到done()的回调将在延迟被解决时被触发。当延迟被拒绝时,附加到fail()的回调将被触发。

在jQuery 1.8之前,then()只是语法糖:

promise.then( doneCallback, failCallback )
// was equivalent to
promise.done( doneCallback ).fail( failCallback )

从1.8开始,then()是pipe()的别名,并返回一个新的promise,有关pipe()的更多信息,请参阅这里。

success()和error()仅在调用ajax()返回的jqXHR对象上可用。它们分别是done()和fail()的别名:

jqXHR.done === jqXHR.success
jqXHR.fail === jqXHR.error

同样,done()不局限于单个回调,它会过滤掉非函数(尽管在1.8版本中有一个字符串错误,应该在1.8.1中修复):

// this will add fn1 to 7 to the deferred's internal callback list
// (true, 56 and "omg" will be ignored)
promise.done( fn1, fn2, true, [ fn3, [ fn4, 56, fn5 ], "omg", fn6 ], fn7 );

fail()也是一样。

.done()终止承诺链,确保没有其他步骤可以附加。这意味着jQuery承诺实现可以抛出任何未处理的异常,因为没有人可以使用.fail()处理它。

实际上,如果您不打算为承诺附加更多步骤,则应该使用.done()。要了解更多细节,请参阅为什么需要兑现承诺

deferred.done ()

添加仅在Deferred被解析时调用的处理程序。您可以添加多个回调被调用。

var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).done(doneCallback);

function doneCallback(result) {
    console.log('Result 1 ' + result);
}

你也可以这样写在上面,

function ajaxCall() {
    var url = 'http://jsonplaceholder.typicode.com/posts/1';
    return $.ajax(url);
}

$.when(ajaxCall()).then(doneCallback, failCallback);

deferred.then ()

当Deferred被解析、拒绝或仍在进行时,添加要调用的处理程序。

var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).then(doneCallback, failCallback);

function doneCallback(result) {
    console.log('Result ' + result);
}

function failCallback(result) {
    console.log('Result ' + result);
}