gpt4 book ai didi

jquery - 什么时候应该使用jQuery deferred的 "then"方法,什么时候应该使用 "pipe"方法?

转载 作者:IT王子 更新时间:2023-10-29 03:25:17 24 4
gpt4 key购买 nike

jQuery 的 Deferred有两个函数可用于实现函数的异步链接:

then()

deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred

doneCallbacks A function, or array of functions, called when the Deferred is resolved.
failCallbacks A function, or array of functions, called when the Deferred is rejected.

pipe()

deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise

doneFilter An optional function that is called when the Deferred is resolved.
failFilter An optional function that is called when the Deferred is rejected.

我知道 then()pipe() 存在的时间要长一些,所以后者肯定会增加一些额外的好处,但我不知道究竟有什么区别。两者采用几乎相同的回调参数,尽管它们的名称不同,而且返回 Deferred 和返回 Promise 之间的区别似乎很小。

我一遍又一遍地阅读官方文档,但总是觉得它们太“密集”,无法真正理解,搜索发现有很多关于一个功能或另一个功能的讨论,但我没有找到任何真正阐明了各自的优缺点。

那么什么时候使用then比较好,什么时候使用pipe比较好?


加法

Felix's excellent answer确实有助于阐明这两个功能的不同之处。但我想知道是否有时 then() 的功能优于 pipe()

很明显 pipe()then() 更强大,而且似乎前者可以做后者可以做的任何事情。使用 then() 的一个原因可能是它的名称反射(reflect)了它作为处理相同数据的函数链的终止的作用。

但是是否有一个用例需要 then() 返回原始的 Deferredpipe() 无法完成 因为它返回了一个新的 Promise

最佳答案

jQuery 1.8 .then 的行为与 .pipe 相同:

Deprecation Notice: As of jQuery 1.8, the deferred.pipe() method is deprecated. The deferred.then() method, which replaces it, should be used instead.

As of jQuery 1.8, the deferred.then() method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated deferred.pipe() method.

下面的示例可能对某些人仍然有帮助。


它们有不同的用途:

  • .then() 将在您想要处理过程结果时使用,即如文档所述,当延迟对象被解析或拒绝时。它与使用 .done().fail() 相同。

  • 您将使用 .pipe() 以某种方式(预)过滤 结果。 .pipe() 回调的返回值将作为参数传递给 donefail 回调。它还可以返回另一个延迟对象,并且将在该延迟对象上注册以下回调。

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

您想使用延迟对象来允许调用 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 调用,而无需公开调用的实际流程/顺序。


一般来说,延迟对象提供了一种有趣的方式来解耦你的代码:)

关于jquery - 什么时候应该使用jQuery deferred的 "then"方法,什么时候应该使用 "pipe"方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9583783/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com