我可以将 Promises 传递给 jQuery.when(),还是只传递 Deferreds?
Posted
技术标签:
【中文标题】我可以将 Promises 传递给 jQuery.when(),还是只传递 Deferreds?【英文标题】:Can I pass Promises to jQuery.when(), or only Deferreds? 【发布时间】:2016-07-25 21:04:09 【问题描述】:jQuery.when() 的documentation 表示此函数需要延迟。但是,它后来也说:
如果将单个参数传递给 jQuery.when() 并且它不是 Deferred 或 Promise...
这似乎暗示它也可以接受 Promises。但是 Promise 不是 Deferreds——它们有 Deferred 方法的一个子集。我想你可以说 Deferred 是 Promise,但 Promise 不是 Deferred。
问题:
-
$.when() 可以接受 Promise 或 Deferreds 吗?这似乎在我的测试中有效。
文档中是否存在错误?我认为应该说 $.when() 接受 Promises,而不仅仅是 Deferreds。
【问题讨论】:
1.是的,它可以。 2. 可能更适合询问 jQuery 开发者。 @Karl-AndréGagnon 2. 好主意 - 我已经提交了这个 jquery 文档错误:github.com/jquery/api.jquery.com/issues/906 @JonathanAquino$.when()
可以接受jQuery.Deferred()
、jQuery.promise()
或本机Promise
。见blog.jquery.com/2016/01/14/jquery-3-0-beta-released。 $.when()
的文档试图描述 $.when()
可以接受一个既不是jQuery.Deferred()
、jQuery
承诺对象也不是本机Promise
的参数,并且.then()
或.done()
回调将处理传递参数作为解析jQuery.Deferred()
@JonathanAquino jQuery 方法的一些特性可能没有详细说明,甚至没有在文档中提及。 jQuery
对象还可以使用文档中未列出的功能。一种方法是查看 jQuery github.com/jquery/jquery 的源代码以与文档中的描述进行比较。您也可以尝试在 IRC/Chat irc.jquery.org 和论坛 forum.jquery.com 提问
@guest271314:在 3.0 真正发布之前,您可以假设 jquery-tagged 问题不使用它(并且 jQuery 文档不涵盖它)。即使这样,我们也可能需要一个新标签,因为它们的行为截然不同。
【参考方案1】:
文档试图传达的是$.when()
将接受既不是jQuery.Deferred()
、jQuery.promise()
也不是Promise
的值;该值将被视为已解析的jQuery.Deferred()
,这将在句子的下一部分进行描述
如果将单个参数传递给
jQuery.when()
并且它不是 Deferred 或 Promise,将被视为已解决的 Deferred 和 任何附加的 doneCallbacks 都会立即执行。
例如
$.when(1).then(function(data)
alert(data)
)
<script src="https://code.jquery.com/jquery-git.js">
</script>
【讨论】:
我在问 $.when 是否可以接受类似承诺的对象。医生说它只接受延期。但在我的测试中,它接受类似 Promise 的对象(即 Deferred.promise())。 @JonathanAquino “文档说它只接受 Deferreds。” 文档在哪里说明了这一点?$.when()
接受任何变量或对象作为参数;不仅jQuery.Deferred()
。 “类似承诺的对象”是什么意思?您想使用$.when()
实现什么目标?
@JonathanAquino "如果将单个参数传递给 jQuery.when() 并且它不是 Deferred 或 Promise,它将被视为已解决的 Deferred 并且附加的任何 doneCallbacks 将被立即执行。” jQuery.when()
documentation
它声明它只接受 api.jquery.com/jquery.when 顶部的 Deferreds - jQuery.when( deferreds )
我的观点是 when() 将 Deferreds 和 Promises 与其他对象区别对待。文档的顶部应该说 jQuery.when(promises),而不是 jQuery.when(deferreds),因为 promises 比 deferreds 更通用。【参考方案2】:
我想你可以说 Deferred 是 Promise,但 Promise 不是 Deferred。
实际上它们是完全不同的接口,只是将 jQuery 混入了 promise API 到它们的 deferred 中。见What are the differences between Deferred, Promise and Future in javascript?
$.when()
可以接受 Promise 或 Deferreds 吗?
是的,两者都可以。但是请注意,当您已经知道有一个 promise 或 deferred 时,调用 $.when
是没有意义的。
文档中有错误吗?
是的,显然。甚至它只是将延迟和承诺视为异步值,这甚至不是事实——而是它进行了某种鸭子类型检查。你会想看看actual implementation:
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) )
然后它调用该值的promise
method(或another promise
method,或实际上任何.promise
方法)并期望返回的对象具有相应的可链接方法来添加侦听器。
【讨论】:
这部分文档似乎实际上是在描述$.when()
接受任何参数 - 不仅是 jQuery.Deferred()
jQuery .promise()
对象或原生 Promise
;并将该参数视为已解析的jQuery.Deferred()
。 OP 在原始问题的引用中省略了句子的其余部分;因此可能会混淆文档引用及其试图传达的内容 - 以及当前的问题。 OP 可能试图询问 jQuery.Deferred()
和 jQuery .promise()
对象之间有什么区别 - 可能还有 Promise
;虽然这在 Question 中并不清楚。
@guest271314:当然,它认为每个人都清楚,任何未被标识为“可承诺”的值都将被直接视为履行值。我的回答只是澄清了什么是“有希望的”,什么不是。
您能否扩展一下“但是请注意,当您已经知道有一个promise 或deferred 时,再调用$.when
是没有意义的。”?我对 Promise 和 Deferred 仍然很模糊,我想稍微解释一下为什么(没有意义)会对我和未来的访问者都有帮助。
@StephenP:我的意思是,你应该只做$.ajax(…).then(…)
,而不是做$.when($.ajax(…)).then(…)
(就像文档中可怕的例子)。 $.when
仅在您有用户(函数的调用者)提供的值并且不知道它们是承诺还是普通值时才有效:$.when(couldBeAnything).then(function(nowSurelyIsPlainValue) …)
@Bergi 你说“但是请注意,当你已经知道有一个 promise 或 deferred 时,调用 $.when 是没有意义的。”我认为 $.when 会将几个 Promise 组合在一起 - 这不是使用它的好理由吗?以上是关于我可以将 Promises 传递给 jQuery.when(),还是只传递 Deferreds?的主要内容,如果未能解决你的问题,请参考以下文章