由于jQuery 1.8 .then
的行为与.pipe
相同:
Deprecation Notice:从jQuery1.8开始,deferred.pipe()
方法已被弃用.应该使用deferred.then()
方法代替它.
和
As of jQuery 1.8, the deferred.then()
method returns a new promise that can filter the status 和 values of a deferred through a function, replacing the now-deprecated deferred.pipe()
method.
下面的例子可能对一些人仍有帮助.
They serve different purposes:
当您想要处理流程的结果时,即如文档所述,当延迟对象被解决或拒绝时,将使用.then()
.这与使用.done()
或.fail()
相同.
You'd use .pipe()
to (pre)filter the result somehow. The return value of a callback to .pipe()
will be passed as argument to the done
和 fail
callbacks. It can also return another deferred object 和 the following callbacks will be registered on this deferred.
That is not the case with .then()
(or .done()
, .fail()
), the return values of the registered callbacks are just ignored.
所以你用的不是either.then()
or.pipe()
.您could将.pipe()
用于与.then()
相同的目的,但是反之亦然.
Example 1
The result of some operation is an array of objects:
[{value: 2}, {value: 4}, {value: 6}]
和 you want to compute the minimum 和 maximum of the values. Lets assume we use two done
callbacks:
deferred.then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
/* do something with "min" */
}).then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
/* do something with "max" */
});
In both cases you have to iterate over the list 和 extract the value from each object.
Wouldn't it be better to somehow extract the values beforeh和 so that you don't have to do this in both callbacks individually? Yes! And that's what we can use .pipe()
for:
deferred.pipe(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values; // [2, 4, 6]
}).then(function(result) {
// result = [2, 4, 6]
var min = Math.min.apply(Math, result);
/* do something with "min" */
}).then(function(result) {
// result = [2, 4, 6]
var max = Math.max.apply(Math, result);
/* do something with "max" */
});
Obviously this is a made up example 和 there are many different (maybe better) ways to solve this problem, but I hope it illustrates the point.
Example 2
考虑一下Ajax调用.有时,您希望在前一个Ajax调用完成后启动一个Ajax调用.一种方法是在done
回调中进行第二个调用:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Now lets assume you want to decouple your code 和 put these two Ajax calls inside a function:
function makeCalls() {
// here we return the return value of `$.ajax().done()`, which
// is the same deferred object as returned by `$.ajax()` alone
return $.ajax(...).done(function() {
// executed after first call
$.ajax(...).done(function() {
// executed after second call
});
});
}
您希望使用deferred对象来允许调用makeCalls
的其他代码为second Ajax调用附加回调,但是
makeCalls().done(function() {
// this is executed after the first Ajax call
});
would not have the desired effect as the second call is made inside a done
callback 和 not accessible from the outside.
解决方案是使用.pipe()
:
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object 和 connected to the one returned
// by the callback passed to `pipe`
return $.ajax(...).pipe(function() {
// executed after first call
return $.ajax(...).done(function() {
// executed after second call
});
});
}
makeCalls().done(function() {
// this is executed after the second Ajax call
});
通过使用.pipe()
,现在可以将回调附加到"内部"Ajax调用,而不必公开调用的实际流/顺序.
一般来说,延迟对象提供了一种有趣的方法来解耦代码:)