从jQuery 1.8开始 .then
行为与.pipe
:
弃用通知:从jQuery 1.8开始,deferred.pipe()
方法已弃用。deferred.then()
代替它的方法,应改为使用。
和
从jQuery 1.8开始,该deferred.then()
方法返回一个新的promise,可以过滤通过函数延迟的状态和值,从而替换现在不推荐使用的deferred.pipe()
方法。
下面的示例可能仍然对某些人有所帮助。
它们有不同的用途:
.then()
每当您要处理过程的结果时,即文档中所说的,当解析或拒绝了延迟的对象时,都将使用。与使用.done()
或相同.fail()
。
您习惯.pipe()
以某种方式(预)过滤结果。回调的返回值.pipe()
将作为参数传递给done
和fail
回调。它还可以返回另一个延迟的对象,并且将在此延迟的对象上注册以下回调。
这是不符合的情况下.then()
(或.done()
,.fail()
),已注册的回调的返回值只是忽略。
因此,这不是你使用两种 .then()
或 .pipe()
。您可以将其.pipe()
用于与.then()
但反之则不成立。
例子1
某些操作的结果是一个对象数组:
[{value: 2}, {value: 4}, {value: 6}]
并且您要计算值的最小值和最大值。假设我们使用两个done
回调:
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" */
});
在这两种情况下,您都必须遍历列表并从每个对象中提取值。
事先以某种方式提取值会更好,这样就不必分别在两个回调中都这样做了吗?是! 这就是我们可以.pipe()
用来:
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" */
});
显然,这是一个虚构的示例,有许多不同(也许更好)的方法可以解决此问题,但我希望它能说明这一点。
例子2
考虑Ajax调用。有时您想在上一个Ajax调用完成后发起一个Ajax调用。一种方法是在done
回调内进行第二个调用:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
现在,假设您要解耦代码并将这两个Ajax调用放入函数中:
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
在第二个 Ajax调用中附加回调。
makeCalls().done(function() {
// this is executed after the first Ajax call
});
不会产生预期的效果,因为第二个调用是在done
回调内部进行的,并且无法从外部进行访问。
解决方案是改为使用.pipe()
:
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object and 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调用中,而无需暴露调用的实际流程/顺序。
通常,延迟对象提供了一种有趣的方式来分离代码:)