I've been reading about jQuery deferreds and promises and I can't see the difference between using .then()
& .done()
for successful callbacks. I know Eric Hynds mentions that .done()
and .success()
map to the same functionality but I'm guessing so does .then()
as all the callbacks are all invoked on a completion of a successful operation.
我一直在阅读有关jQuery延迟和承诺的文章,我看不出使用then()和.done()进行成功回调的区别。我知道Eric Hynds提到了.done()和.success()映射到相同的功能,但我猜也是如此。
Can anyone please enlighten me to the correct usage?
谁能指点我正确的用法吗?
Many thanks
非常感谢
8 个解决方案
#1
503
The callbacks attached to done()
will be fired when the deferred is resolved. The callbacks attached to fail()
will be fired when the deferred is rejected.
当解决延迟时,将触发对done()的回调。当拒绝递延时,连接到fail()的回调将被触发。
Prior to jQuery 1.8, then()
was just syntactic sugar:
在jQuery 1.8之前,()只是语法糖:
promise.then( doneCallback, failCallback )
// was equivalent to
promise.done( doneCallback ).fail( failCallback )
As of 1.8, then()
is an alias for pipe()
and returns a new promise, see here for more information on pipe()
.
对于1.8,then()是pipe()的别名,并返回一个新的承诺,更多关于pipe()的信息请参见这里。
success()
and error()
are only available on the jqXHR
object returned by a call to ajax()
. They are simple aliases for done()
and fail()
respectively:
成功()和error()只在调用ajax()返回的jqXHR对象上可用。它们分别是done()和fail()的简单别名:
jqXHR.done === jqXHR.success
jqXHR.fail === jqXHR.error
Also, done()
is not limited to a single callback and will filter out non-functions (though there is a bug with strings in version 1.8 that should be fixed in 1.8.1):
同样,done()并不局限于一个回调,它将过滤掉非函数(尽管在version 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 );
Same goes for fail()
.
失败也是一样()。
#2
354
There is also difference in way that return results are processed (its called chaining, done
doesn't chain while then
produces call chains)
在处理返回结果的方式上也有差异(它称为链接,在生成调用链时没有进行链)
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)
})
The following results will get logged:
将记录以下结果:
abc
123
undefined
While
而
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)
})
will get the following:
将得到以下几点:
abc
abc
abc
---------- Update:
- - - - - - - - - - -更新:
Btw. I forgot to mention, if you return a Promise instead of atomic type value, the outer promise will wait until inner promise resolves:
顺便说一句。我忘了说,如果你返回的是一个承诺而不是原子类型的值,那么外在的承诺将会等到内在的承诺解决:
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
})
in this way it becomes very straightforward to compose parallel or sequential asynchronous operations such as:
这样,编写并行或顺序异步操作就变得非常简单,例如:
// 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
})
The above code issues two http requests in parallel thus making the requests complete sooner, while below those http requests are being run sequentially thus reducing server load
上面的代码并行地发出两个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
})
#3
49
.done()
has only one callback and it is the success callback
.done()只有一个回调,它是success回调
.then()
has both success and fail callbacks
然后()有成功的和失败的回调
.fail()
has only one fail callback
.fail()只有一个fail callback
so it is up to you what you must do... do you care if it succeeds or if it fails?
所以你必须做什么就看你自己了……你在乎它成功还是失败?
#4
12
deferred.done()
adds handlers to be called only when Deferred is resolved. You can add multiple callbacks to be called.
添加仅在解决延迟时才调用的处理程序。您可以添加要调用的多个回调。
var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).done(doneCallback);
function doneCallback(result) {
console.log('Result 1 ' + result);
}
You can also write above like this,
你也可以这样写,
function ajaxCall() {
var url = 'http://jsonplaceholder.typicode.com/posts/1';
return $.ajax(url);
}
$.when(ajaxCall()).then(doneCallback, failCallback);
deferred.then()
adds handlers to be called when Deferred is resolved, rejected or still in progress.
添加在解决、拒绝或仍在进行时调用的处理程序。
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);
}
#5
6
There is actually a pretty critical difference, insofar as jQuery's Deferreds are meant to be an implementations of Promises (and jQuery3.0 actually tries to bring them into spec).
实际上有一个非常关键的区别,因为jQuery的延迟是承诺的实现(jQuery3.0实际上试图将它们引入spec)。
The key difference between done/then is that
两者之间的关键区别在于
-
.done()
ALWAYS returns the same Promise/wrapped values it started with, regardless of what you do or what you return. - .done()总是返回与开始时相同的承诺/包装值,无论您做什么或返回什么。
-
.then()
always returns a NEW Promise, and you are in charge of controlling what that Promise is based on what the function you passed it returned. - 然后()总是返回一个新的承诺,您负责根据传递的函数返回的内容控制该承诺是什么。
Translated from jQuery into native ES2015 Promises, .done()
is sort of like implementing a "tap" structure around a function in a Promise chain, in that it will, if the chain is in the "resolve" state, pass a value to a function... but the result of that function will NOT affect the chain itself.
从jQuery转换到本地ES2015承诺,.done()有点像在承诺链中实现一个函数的“tap”结构,如果链处于“resolve”状态,那么它就会将一个值传递给一个函数……但是这个函数的结果不会影响链本身。
const doneWrap = fn => x => { fn(x); return x };
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(doneWrap(console.log.bind(console)));
$.Deferred().resolve(5)
.done(x => x + 1)
.done(console.log.bind(console));
Those will both log 5, not 6.
它们都是log 5,而不是6。
Note that I used done and doneWrap to do logging, not .then. That's because console.log functions don't actually return anything. And what happens if you pass .then a function that doesn't return anything?
注意,我使用done和doneWrap来做日志记录,而不是then。这是因为控制台。日志函数实际上不会返回任何东西。如果你传递一个函数,它不会返回任何东西,会发生什么?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
That will log:
将日志:
5
5
undefined
未定义的
What happened? When I used .then and passed it a function that didn't return anything, it's implicit result was "undefined"... which of course returned a Promise[undefined] to the next then method, which logged undefined. So the original value we started with was basically lost.
发生了什么事?当我使用。然后给它传递一个不返回任何东西的函数时,它的隐式结果是“未定义的”……它当然会向next then方法返回一个承诺[undefined],该方法记录为undefined。所以我们开始时的原始值基本上是丢失的。
.then()
is, at heart, a form of function composition: the result of each step is used as the argument for the function in the next step. That's why .done is best thought of as a "tap"-> it's not actually part of the composition, just something that sneaks a look at the value at a certain step and runs a function at that value, but doesn't actually alter the composition in any way.
然后()本质上是函数合成的一种形式:每一步的结果作为下一步函数的参数。这就是为什么。done被认为是一个“tap”->实际上它并不是合成的一部分,它只是在特定的步骤中偷偷地查看这个值并在这个值上运行一个函数,但实际上并没有以任何方式改变这个合成。
This is a pretty fundamental difference, and there's a probably a good reason why native Promises don't have a .done method implemented themselves. We don't eve have to get into why there's no .fail method, because that's even more complicated (namely, .fail/.catch are NOT mirrors of .done/.then -> functions in .catch that return bare values do not "stay" rejected like those passed to .then, they resolve!)
这是一个非常基本的区别,并且有一个很好的理由可以解释为什么native promise没有自己实现的。done方法。我们不必解释为什么没有。fail方法,因为它更复杂(即。fail/)。捕获不是.done的镜像。然后->函数在。catch中返回裸值,不要像传递给它们的那样被拒绝。
#6
4
then()
always means it will be called in whatever case. But the parameters passing are different in different jQuery versions.
then()在任何情况下都意味着它将被调用。但是传递的参数在不同的jQuery版本中是不同的。
Prior to jQuery 1.8, then()
equals done().fail()
. And all of the callback functions share same parameters.
在jQuery 1.8之前,然后()等于done().fail()。所有回调函数都有相同的参数。
But as of jQuery 1.8, then()
returns a new promise, and if it has return a value, it will be passed into the next callback function.
但是,在jQuery 1.8中,then()返回一个新的承诺,如果它返回一个值,它将被传递到下一个回调函数中。
Let's see the following example:
让我们看看下面的例子:
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 );
Prior to jQuery 1.8, the answer should be
在jQuery 1.8之前,答案应该是
result = 3
result = 3
result = 3
All result
takes 3. And then()
function always passes the same deferred object to the next function.
所有结果需要3。然后()函数总是将相同的递延对象传递给下一个函数。
But as of jQuery 1.8, the result should be:
但是jQuery 1.8的结果应该是:
result = 3
result = 7
result = NaN
Because the first then()
function returns a new promise, and the value 7 (and this is the only parameter that will passed on)is passed to the next done()
, so the second done()
write result = 7
. The second then()
takes 7 as the value of a
and takes undefined
as the value of b
, so the second then()
returns a new promise with the parameter NaN, and the last done()
prints NaN as its result.
因为第一个then()函数返回一个新的承诺,值7(这是唯一要传递的参数)被传递给下一个done(),所以第二个done()写入result = 7。第二个then()以7为a的值,以undefined为b的值,因此第二个then()用参数NaN返回一个新的承诺,最后一个done()输出NaN作为结果。
#7
0
There is a very simple mental mapping in response that was a bit hard to find in the other answers:
有一种非常简单的心理映射反应很难在其他答案中找到:
-
done
implementstap
as in bluebird Promises像蓝鸟承诺的那样实现tap
-
then
implementsthen
as in ES6 Promises然后实现ES6承诺
#8
-5
.done()
terminates the promise chain, making sure nothing else can attach further steps. This means that the jQuery promise implementation can throw any unhandled exception, since no one can possible handle it using .fail()
.
.done()终止承诺链,确保没有其他东西可以附加进一步的步骤。这意味着jQuery承诺实现可以抛出任何未处理的异常,因为没有人可以使用.fail()处理它。
In practical terms, if you do not plan to attach more steps to a promise, you should use .done()
. For more details see why promises need to be done
实际上,如果您不打算为一个承诺附加更多的步骤,您应该使用.done()。要了解更多细节,请了解为什么需要做出承诺。
#1
503
The callbacks attached to done()
will be fired when the deferred is resolved. The callbacks attached to fail()
will be fired when the deferred is rejected.
当解决延迟时,将触发对done()的回调。当拒绝递延时,连接到fail()的回调将被触发。
Prior to jQuery 1.8, then()
was just syntactic sugar:
在jQuery 1.8之前,()只是语法糖:
promise.then( doneCallback, failCallback )
// was equivalent to
promise.done( doneCallback ).fail( failCallback )
As of 1.8, then()
is an alias for pipe()
and returns a new promise, see here for more information on pipe()
.
对于1.8,then()是pipe()的别名,并返回一个新的承诺,更多关于pipe()的信息请参见这里。
success()
and error()
are only available on the jqXHR
object returned by a call to ajax()
. They are simple aliases for done()
and fail()
respectively:
成功()和error()只在调用ajax()返回的jqXHR对象上可用。它们分别是done()和fail()的简单别名:
jqXHR.done === jqXHR.success
jqXHR.fail === jqXHR.error
Also, done()
is not limited to a single callback and will filter out non-functions (though there is a bug with strings in version 1.8 that should be fixed in 1.8.1):
同样,done()并不局限于一个回调,它将过滤掉非函数(尽管在version 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 );
Same goes for fail()
.
失败也是一样()。
#2
354
There is also difference in way that return results are processed (its called chaining, done
doesn't chain while then
produces call chains)
在处理返回结果的方式上也有差异(它称为链接,在生成调用链时没有进行链)
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)
})
The following results will get logged:
将记录以下结果:
abc
123
undefined
While
而
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)
})
will get the following:
将得到以下几点:
abc
abc
abc
---------- Update:
- - - - - - - - - - -更新:
Btw. I forgot to mention, if you return a Promise instead of atomic type value, the outer promise will wait until inner promise resolves:
顺便说一句。我忘了说,如果你返回的是一个承诺而不是原子类型的值,那么外在的承诺将会等到内在的承诺解决:
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
})
in this way it becomes very straightforward to compose parallel or sequential asynchronous operations such as:
这样,编写并行或顺序异步操作就变得非常简单,例如:
// 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
})
The above code issues two http requests in parallel thus making the requests complete sooner, while below those http requests are being run sequentially thus reducing server load
上面的代码并行地发出两个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
})
#3
49
.done()
has only one callback and it is the success callback
.done()只有一个回调,它是success回调
.then()
has both success and fail callbacks
然后()有成功的和失败的回调
.fail()
has only one fail callback
.fail()只有一个fail callback
so it is up to you what you must do... do you care if it succeeds or if it fails?
所以你必须做什么就看你自己了……你在乎它成功还是失败?
#4
12
deferred.done()
adds handlers to be called only when Deferred is resolved. You can add multiple callbacks to be called.
添加仅在解决延迟时才调用的处理程序。您可以添加要调用的多个回调。
var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).done(doneCallback);
function doneCallback(result) {
console.log('Result 1 ' + result);
}
You can also write above like this,
你也可以这样写,
function ajaxCall() {
var url = 'http://jsonplaceholder.typicode.com/posts/1';
return $.ajax(url);
}
$.when(ajaxCall()).then(doneCallback, failCallback);
deferred.then()
adds handlers to be called when Deferred is resolved, rejected or still in progress.
添加在解决、拒绝或仍在进行时调用的处理程序。
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);
}
#5
6
There is actually a pretty critical difference, insofar as jQuery's Deferreds are meant to be an implementations of Promises (and jQuery3.0 actually tries to bring them into spec).
实际上有一个非常关键的区别,因为jQuery的延迟是承诺的实现(jQuery3.0实际上试图将它们引入spec)。
The key difference between done/then is that
两者之间的关键区别在于
-
.done()
ALWAYS returns the same Promise/wrapped values it started with, regardless of what you do or what you return. - .done()总是返回与开始时相同的承诺/包装值,无论您做什么或返回什么。
-
.then()
always returns a NEW Promise, and you are in charge of controlling what that Promise is based on what the function you passed it returned. - 然后()总是返回一个新的承诺,您负责根据传递的函数返回的内容控制该承诺是什么。
Translated from jQuery into native ES2015 Promises, .done()
is sort of like implementing a "tap" structure around a function in a Promise chain, in that it will, if the chain is in the "resolve" state, pass a value to a function... but the result of that function will NOT affect the chain itself.
从jQuery转换到本地ES2015承诺,.done()有点像在承诺链中实现一个函数的“tap”结构,如果链处于“resolve”状态,那么它就会将一个值传递给一个函数……但是这个函数的结果不会影响链本身。
const doneWrap = fn => x => { fn(x); return x };
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(doneWrap(console.log.bind(console)));
$.Deferred().resolve(5)
.done(x => x + 1)
.done(console.log.bind(console));
Those will both log 5, not 6.
它们都是log 5,而不是6。
Note that I used done and doneWrap to do logging, not .then. That's because console.log functions don't actually return anything. And what happens if you pass .then a function that doesn't return anything?
注意,我使用done和doneWrap来做日志记录,而不是then。这是因为控制台。日志函数实际上不会返回任何东西。如果你传递一个函数,它不会返回任何东西,会发生什么?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
That will log:
将日志:
5
5
undefined
未定义的
What happened? When I used .then and passed it a function that didn't return anything, it's implicit result was "undefined"... which of course returned a Promise[undefined] to the next then method, which logged undefined. So the original value we started with was basically lost.
发生了什么事?当我使用。然后给它传递一个不返回任何东西的函数时,它的隐式结果是“未定义的”……它当然会向next then方法返回一个承诺[undefined],该方法记录为undefined。所以我们开始时的原始值基本上是丢失的。
.then()
is, at heart, a form of function composition: the result of each step is used as the argument for the function in the next step. That's why .done is best thought of as a "tap"-> it's not actually part of the composition, just something that sneaks a look at the value at a certain step and runs a function at that value, but doesn't actually alter the composition in any way.
然后()本质上是函数合成的一种形式:每一步的结果作为下一步函数的参数。这就是为什么。done被认为是一个“tap”->实际上它并不是合成的一部分,它只是在特定的步骤中偷偷地查看这个值并在这个值上运行一个函数,但实际上并没有以任何方式改变这个合成。
This is a pretty fundamental difference, and there's a probably a good reason why native Promises don't have a .done method implemented themselves. We don't eve have to get into why there's no .fail method, because that's even more complicated (namely, .fail/.catch are NOT mirrors of .done/.then -> functions in .catch that return bare values do not "stay" rejected like those passed to .then, they resolve!)
这是一个非常基本的区别,并且有一个很好的理由可以解释为什么native promise没有自己实现的。done方法。我们不必解释为什么没有。fail方法,因为它更复杂(即。fail/)。捕获不是.done的镜像。然后->函数在。catch中返回裸值,不要像传递给它们的那样被拒绝。
#6
4
then()
always means it will be called in whatever case. But the parameters passing are different in different jQuery versions.
then()在任何情况下都意味着它将被调用。但是传递的参数在不同的jQuery版本中是不同的。
Prior to jQuery 1.8, then()
equals done().fail()
. And all of the callback functions share same parameters.
在jQuery 1.8之前,然后()等于done().fail()。所有回调函数都有相同的参数。
But as of jQuery 1.8, then()
returns a new promise, and if it has return a value, it will be passed into the next callback function.
但是,在jQuery 1.8中,then()返回一个新的承诺,如果它返回一个值,它将被传递到下一个回调函数中。
Let's see the following example:
让我们看看下面的例子:
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 );
Prior to jQuery 1.8, the answer should be
在jQuery 1.8之前,答案应该是
result = 3
result = 3
result = 3
All result
takes 3. And then()
function always passes the same deferred object to the next function.
所有结果需要3。然后()函数总是将相同的递延对象传递给下一个函数。
But as of jQuery 1.8, the result should be:
但是jQuery 1.8的结果应该是:
result = 3
result = 7
result = NaN
Because the first then()
function returns a new promise, and the value 7 (and this is the only parameter that will passed on)is passed to the next done()
, so the second done()
write result = 7
. The second then()
takes 7 as the value of a
and takes undefined
as the value of b
, so the second then()
returns a new promise with the parameter NaN, and the last done()
prints NaN as its result.
因为第一个then()函数返回一个新的承诺,值7(这是唯一要传递的参数)被传递给下一个done(),所以第二个done()写入result = 7。第二个then()以7为a的值,以undefined为b的值,因此第二个then()用参数NaN返回一个新的承诺,最后一个done()输出NaN作为结果。
#7
0
There is a very simple mental mapping in response that was a bit hard to find in the other answers:
有一种非常简单的心理映射反应很难在其他答案中找到:
-
done
implementstap
as in bluebird Promises像蓝鸟承诺的那样实现tap
-
then
implementsthen
as in ES6 Promises然后实现ES6承诺
#8
-5
.done()
terminates the promise chain, making sure nothing else can attach further steps. This means that the jQuery promise implementation can throw any unhandled exception, since no one can possible handle it using .fail()
.
.done()终止承诺链,确保没有其他东西可以附加进一步的步骤。这意味着jQuery承诺实现可以抛出任何未处理的异常,因为没有人可以使用.fail()处理它。
In practical terms, if you do not plan to attach more steps to a promise, you should use .done()
. For more details see why promises need to be done
实际上,如果您不打算为一个承诺附加更多的步骤,您应该使用.done()。要了解更多细节,请了解为什么需要做出承诺。