deferred翻译 jQuery推迟并承诺-.then()vs.done()




deferred翻译 (7)

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

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

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

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

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

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

另外, done()并不局限于单个回调函数,它将过滤非函数(尽管1.8版本中的字符串存在一个bug,应该在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()

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

任何人都可以请启发我正确的用法?

非常感谢



Answer #2

deferred.done()

添加处理程序仅在解决延迟时才被调用。 您可以添加多个要调用的回调。

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

Answer #3

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

所有result都是3, then()函数总是将相同的延迟对象传递给下一个函数。

但从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作为结果。


Answer #4

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

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


Answer #5

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

.then()具有成功和失败回调

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

所以这取决于你你必须做什么......你关心它是否成功或失败了吗?


Answer #6

处理返回结果的方式也有所不同(它称为链接, done不产生链接, then产生调用链)

promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return 123;
}).then(function (x){
    console.log(x);
}).then(function (x){
    console.log(x)
})

以下结果将被记录:

abc
123
undefined

promise.done(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return 123;
}).done(function (x){
    console.log(x);
}).done(function (x){
    console.log(x)
})

将得到以下内容:

abc
abc
abc

----------更新:

顺便说一句。 我忘了提及,如果你返回一个Promise而不是原子类型的值,那么外层承诺将等到内层承诺解决:

promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return $http.get('/some/data').then(function (result) {
        console.log(result); // suppose result === "xyz"
        return result;
    });
}).then(function (result){
    console.log(result); // result === xyz
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})

通过这种方式,构成并行或连续的异步操作变得非常简单,例如:

// Parallel http requests
promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);

    var promise1 = $http.get('/some/data?value=xyz').then(function (result) {
        console.log(result); // suppose result === "xyz"
        return result;
    });

    var promise2 = $http.get('/some/data?value=uvm').then(function (result) {
        console.log(result); // suppose result === "uvm"
        return result;
    });

    return promise1.then(function (result1) {
        return promise2.then(function (result2) {
           return { result1: result1, result2: result2; }
        });
    });
}).then(function (result){
    console.log(result); // result === { result1: 'xyz', result2: 'uvm' }
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})

上面的代码并行发出两个http请求,从而使得请求更快完成,而低于这些http请求的请求将顺序运行,从而减少服务器负载

// Sequential http requests
promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);

    return $http.get('/some/data?value=xyz').then(function (result1) {
        console.log(result1); // suppose result1 === "xyz"
        return $http.get('/some/data?value=uvm').then(function (result2) {
            console.log(result2); // suppose result2 === "uvm"
            return { result1: result1, result2: result2; };
        });
    });
}).then(function (result){
    console.log(result); // result === { result1: 'xyz', result2: 'uvm' }
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})




jquery-deferred