【问题标题】:Does jQuery.Deferred have a bug when a jQuery.Deferred object is passed to deferred.resolve?将 jQuery.Deferred 对象传递给 deferred.resolve 时,jQuery.Deferred 是否有错误?
【发布时间】:2017-09-29 15:32:57
【问题描述】:

给出使用Promise构造函数的代码

let promise = () => new Promise(resolve => resolve(1));

new Promise((resolve, reject) => {
  setTimeout(() => reject("10 seconds exceeded"), 10000);
  resolve(promise())
})
.then(data => console.log(data))
.catch(err => console.error(err));

1 记录在console

鉴于使用 jQuery.Deferred 的等效代码,jQuery.deferred 对象记录在 .then(),而不是传递给 jQuery.deferred.resolve 的值

let promise = () => new $.Deferred(dfd => dfd.resolve(1));

new $.Deferred(dfd => {
  setTimeout(() => dfd.reject("10 seconds exceeded"), 10000);
  dfd.resolve(promise());
})
.then(data => console.log(data))
.fail(err => console.error(err));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>

虽然将jQuery.deferred 承诺对象传递给.then() 确实返回预期结果

let promise = () => new $.Deferred(dfd => dfd.resolve(1));

new $.Deferred(dfd => {
  setTimeout(() => dfd.reject("10 seconds exceeded"), 10000);
  promise().then(data => dfd.resolve(data));
})
.then(data => console.log(data))
.fail(err => console.error(err));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>

输出的 jQuery 错误是否与 jQuery 的 Promisespecification 实现相关?

【问题讨论】:

  • jQuery 从未实现 Promise
  • 你用的是什么版本的jQuery?
  • 为什么你既解决又拒绝承诺?直接的resolve 将永远获胜。
  • 你可以尝试传递一个 jQuery 承诺而不是一个 jQuery deferred 吗?
  • @Bergi stacksn-ps 使用的 jQuery 版本是 3.2.1,虽然 2x 返回相同的结果

标签: javascript jquery promise jquery-deferred


【解决方案1】:

这不是错误,但可能是缺少的功能。 jQuery 从未尝试实现标准的Promise 构造函数,它的Deferred 构造函数做了一些完全不同的事情。诚然,如果resolve 实际上满足,他们肯定会混淆标准术语;然而,jQuery 的实现确实早于标准,所以这并不奇怪。

输出的 jQuery 错误是否与 jQuery 的 Promise/A+ 规范实现相关?

不,Promise/A+ 规范只关注then 函数的行为,而不关注promise 构造。在 jQuery 的 promise 实现中有 were indeed many inherent problems,但是从版本 3 开始,这些至少已经修复(can be tested),所以 jQuery promise 实例现在可以与所有其他实现互操作。

【讨论】:

  • @guest271314 这只是意味着像Promise.resolve(jQuery.Deferred(…).then(x =&gt; Promise.resolve())) 这样的东西是开箱即用的,这样可以很容易地删除 jQuery 并改用正确的实现。
  • 我知道你不能说明为什么 jQuery 实现决定实现或不实现一个特性,尽管你有任何迹象表明 jQuery 作者和贡献者知道Promise 模式之间的明显区别和jQuery.Deferred() 模式? “不,Promise/A+ 规范只关注then 函数的行为” 不是.then() 期望有Promise 的值可用,而不是@987654333 @对象本身?即jQuery.deferred.then的实现是否符合规范?
  • 当然jQuery.deferred.then的结果与使用与原生.then()相同模式的输出不一致
  • @guest271314 是的,每个人都知道 deferred 和 promise 构造函数模式之间的明显差异(resolve 没有解决但实现只是另一个),但我不知道任何意图做点什么。是的,jQuery-v3 的then 符合规范——它调用回调的任何值都符合承诺。有不止一种实现允许使用其他 Promise 对象来实现 Promise(尽管 ES6 不是其中之一)。
  • @guest271314 你没有用1 解析,你.resolved 的返回值为promise()。显然 jQuery 直接将其作为履行值。没有什么可以说这应该有不同的工作方式 - 除了命名差异 resolvefulfill - 因为没有延迟的规范。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2015-01-26
  • 2018-01-01
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多