自从jQuery 1.8版本以后,
.then()
方法的行为与
.pipe()
方法相同:
废弃通知:自jQuery 1.8版本起,deferred.pipe()
方法已被弃用。应使用替代它的deferred.then()
方法。
并且
自jQuery 1.8版本起,deferred.then()
方法返回一个新的promise。可以通过函数过滤deferred对象的状态和值,替代现在已过时的deferred.pipe()
方法。
以下示例对某些人仍然有帮助。
它们有不同的用途:
.then()
适用于您想要使用过程结果的情况,例如当deferred对象被解析或拒绝时。这与使用.done()
或.fail()
相同。
您可以使用.pipe()
来(预)过滤结果。回调函数的返回值将作为参数传递给done
和fail
回调函数。它也可以返回另一个deferred对象,接下来的回调函数将在该deferred对象上注册。
这不是.then()
(或.done()
, .fail()
)的情况,注册回调函数的返回值会被忽略。
因此,并不是您只使用.then()
或.pipe()
。您可以使用.pipe()
来实现与.then()
相同的目的,但反之则不成立。
示例1
某些操作的结果是对象数组:
[{value: 2}, {value: 4}, {value: 6}]
如果您想计算值的最小值和最大值。假设我们使用两个done
回调函数:
deferred.then(function(result) {
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
}).then(function(result) {
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
});
在这两种情况下,都需要迭代列表并从每个对象中提取值。
事先提取值是否更好,这样您就不必在两个回调函数中分别执行此操作?是的!这就是我们可以使用 .pipe()
的原因:
deferred.pipe(function(result) {
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values;
}).then(function(result) {
var min = Math.min.apply(Math, result);
}).then(function(result) {
var max = Math.max.apply(Math, result);
});
显然这只是一个虚构的例子,解决这个问题有许多不同的(也许更好的)方法,但我希望它能说明问题。
例子2
考虑Ajax调用。有时您希望在先前的调用完成后启动第二个调用。一种方法是在done
回调内部进行第二次调用:
$.ajax(...).done(function() {
$.ajax(...).done(function() {
});
});
现在假设你想要将代码解耦并将这两个Ajax调用放到一个函数中:
function makeCalls() {
return $.ajax(...).done(function() {
$.ajax(...).done(function() {
});
});
}
您想使用延迟对象来允许调用makeCalls
的其他代码附加回调函数到第二个Ajax调用,但是
makeCalls().done(function() {
});
由于第二个调用是在回调函数 done
中进行的,而不是从外部进行的,因此使用 .pipe()
可以解决这个问题。
function makeCalls() {
return $.ajax(...).pipe(function() {
return $.ajax(...).done(function() {
});
});
}
makeCalls().done(function() {
});
通过使用.pipe()
,您现在可以将回调函数附加到“内部”Ajax调用,而不必暴露调用的实际流程/顺序。
总体上,延迟对象为解耦代码提供了一种有趣的方法 :)