- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
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()
返回原始的 Deferred
而 pipe() 无法完成
因为它返回了一个新的 Promise
?
最佳答案
自 jQuery 1.8 .then
的行为与 .pipe
相同:
Deprecation Notice: As of jQuery 1.8, the
deferred.pipe()
method is deprecated. Thedeferred.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-deprecateddeferred.pipe()
method.
下面的示例可能对某些人仍然有帮助。
它们有不同的用途:
.then()
将在您想要处理过程结果时使用,即如文档所述,当延迟对象被解析或拒绝时。它与使用 .done()
或 .fail()
相同。
您将使用 .pipe()
以某种方式(预)过滤 结果。 .pipe()
回调的返回值将作为参数传递给 done
和 fail
回调。它还可以返回另一个延迟对象,并且将在该延迟对象上注册以下回调。
.then()
(或.done()
、.fail()
)不是这种情况,返回值的已注册回调将被忽略。
所以不是你使用或者 .then()
或者 .pipe()
。您可以将 .pipe()
用于与 .then()
相同的目的,但反过来不成立。
一些操作的结果是一个对象数组:
[{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" */
});
显然这是一个虚构的例子,有许多不同的(可能更好的)方法可以解决这个问题,但我希望它能说明这一点。
考虑 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/
在带有 jQuery 的 CoffeeScript 中,以下语句有什么区别吗? jQuery ($) -> jQuery -> $ - > 最佳答案 第一个与其他两个不同,就像在纯 JavaScr
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭13 年前。 Improve th
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
这个问题可能听起来很愚蠢,但请耐心等待,因为我完全是初学者。我下载了两个 jQuery 版本,开发版本和生产版本。我想知道作为学习 jQuery 的初学者,什么更适合我。 最佳答案 如果您对 jQue
The documentation说要使用 1.6.4,但我们现在已经升级到 1.7.2。 我可以在 jQuery Mobile 中使用最新版本的 jQuery 吗? 最佳答案 您当然可以,但如果您想
我在这里看到这个不错的 jquery 插件:prettyphoto jquery lightbox有没有办法只用一个简单的jquery来实现这样的效果。 我只需要弹出和内联内容。你的回复有很大帮助。
很明显我正在尝试做一些 jQuery 不喜欢的事情。 我正在使用 javascript 上传图片。每次上传图片时,我都希望它可见,并附加一个有效的删除脚本。显示工作正常,删除则不然,因为当我用 fir
这两个哪个是正确的? jQuery('someclass').click(function() { alert("I've been clicked!"); }); 或 jQuery('somec
我正在寻找一个具有以下格式的插件 if (jQuery)(function ($) { -- plugin code -- })(jQuery); 我明白 (function ($)
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭10 年前。 Improv
我知道这个问题已经被问过几次了,但想知道您是否可以帮助我解决这个问题。 背景:我尝试创建一个使用 Ajax 提交的表单(jQuery 表单提交)。我已经工作得很好,然后我想在表单上得到验证。我可以使用
我正在使用无处不在的jquery validate plugin用于表单验证。它支持使用metadata plugin用于向表单元素添加验证规则。 我正在使用此功能。当验证查找这些规则时,它会对元素进
我更喜欢为我一直在开发的网络社区添加实用的视觉效果,但随着事情开始堆积,我担心加载时间。 拥有用户真的更快吗加载(希望是缓存的)副本来自 Google 存储库的 jquery? 是否使用 jQuery
这个问题已经有答案了: Slide right to left? (17 个回答) 已关闭 9 年前。 你能告诉我有没有办法在 jQuery 中左右滑动而不使用 jQuery UI 和 jQuery
我如何找出最适合某种情况的方法?任何人都可以提供一些示例来了解功能和性能方面的差异吗? 最佳答案 XMLHttpRequest 是原始浏览器对象,jQuery 将其包装成一种更有用和简化的形式以及跨浏
运行时 php bin/console oro:assets:build ,我有 11 个这样的错误: ERROR in ../node_modules/jquery-form/src/jquery.
我试图找到 jQuery.ajax() 在源代码中的定义位置。但是,使用 grep 似乎不起作用。 在哪里? 谢谢。 > grep jQuery.ajax src/* src/ajax.js:// B
$.fn.sortByDepth = function() { var ar = []; var result = $([]); $(this).each(function()
我的页面上有多个图像。为了检测损坏的图像,我使用了在 SO 上找到的这个。 $('.imgRot').one('error',function(){ $(this).attr('src','b
我在理解 $ 符号作为 jQuery 函数的别名时遇到了一些麻烦,尤其是在插件中。你能解释一下 jQuery 如何实现这种别名:它如何定义 '$' 作为 jQuery 函数的别名?这是第一个问题。 其
我是一名优秀的程序员,十分优秀!