gpt4 book ai didi

javascript - jQuery.Deferred.prototype.then : returns an object with behaviour I don't understand

转载 作者:行者123 更新时间:2023-11-30 14:53:24 28 4
gpt4 key购买 nike

我在使用 jQuery.Deferred.prototype.then 时遇到了问题,所以我决定查看 jQuery 的测试套件来检查我是否正确理解此方法的行为。与我的问题最相关的测试如下,来自3.2.1 版:

https://github.com/jquery/jquery/blob/3.2.1/test/unit/deferred.js#L133-L168

注意:

  • Deferred 对象在第 153 行被拒绝。
  • done 在第 144 和 164 行被调用。我对 QUnit 不是很熟悉,但是很清楚我认为测试会失败,除非传递给 done 的回调实际上被执行了。
  • 当且仅当 Deferred 对象时,传递给 done 的回调应该被执行是解决了,不是拒绝了。(这是我对 Deferred 的理解 documentation ,无论如何。)

但以上3点不可能都是正确的!

done 的两次调用都是在由返回的对象上进行的jQuery.Deferred.prototype.then。我可以解释code if 我假设,在 then 返回的 Promise 对象中,最终状态与原始状态不同延迟。但是,我在 jQuery 中找不到任何提示文档。

尽可能简短地提出我的问题:什么时候我上面链接的代码被执行了,是回调传递给执行的 done,如果是这样,为什么?

更新

这是我上面链接的代码(添加了一些注释以指示行号):

QUnit.test( "jQuery.Deferred.then - filtering (fail)", function( assert ) {

assert.expect( 4 );

var value1, value2, value3,
defer = jQuery.Deferred(),
piped = defer.then( null, function( a, b ) {
return a * b;
} ),
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );

piped.done( function( result ) { // Line 144
value3 = result;
} );

defer.fail( function( a, b ) {
value1 = a;
value2 = b;
} );

defer.reject( 2, 3 ).then( null, function() { // Line 153
assert.strictEqual( value1, 2, "first reject value ok" );
assert.strictEqual( value2, 3, "second reject value ok" );
assert.strictEqual( value3, 6, "result of filter ok" );
done.pop().call();
} );

jQuery.Deferred().resolve().then( null, function() {
assert.ok( false, "then should not be called on resolve" );
} ).then( done.pop() );

jQuery.Deferred().reject().then( null, jQuery.noop ).done( // Line 164
function( value ) {
assert.strictEqual( value, undefined, "then fail callback can return undefined/null" );
done.pop().call();
} );
} );

更新 2

事实证明,随着 2016 年 6 月 jQuery 3 的发布,then 的行为发生了变化。 post在 jQuery 博客上,宣布新版本:

The resolution state of a Deferred created by .then() is now controlled by its callbacks—exceptions become rejection values and non-thenable returns become fulfillment values. Previously, returns from rejection handlers became rejection values.

documentation then 尚未更新。

最佳答案

The Deferred object is rejected on line 153.

这是一个非常可怕的测试,同时做很多事情。有许多延迟和许多 promise ,其中一些彼此完全无关。

请注意,在第 153 行,defer deferred 被拒绝,它确实附加了一个 .fail 回调,附加了一个 .then 回调(它创建了 piped),以及更多的 .then 回调附加在第 153 行本身。

done is called on lines 144 and 164. I'm not that familiar with QUnit, but it's pretty clear to me that the test will fail unless the callbacks that are passed to done are actually executed.

没有。您不能混淆延迟的 .done 方法和 QUnit 的 done 回调。事实上,done 数组中存储了三个 QUnit 回调,每个回调都是由 assert.async() 创建的。

The callbacks passed to done should be executed if and only if the Deferred object is resolved, not rejected.

是的,这正是发生的事情。请注意,第 144 和 164 行中的 .done 调用不是针对被拒绝的 defer 延迟的,而是针对 piped promise 和另一个匿名的.then(null, jQuery.noop) 创建的 promise 。这些 promise 不会被拒绝,它们通过作为第二个参数传递给相应 .then 调用的 onrejected 回调的结果来实现。

关于javascript - jQuery.Deferred.prototype.then : returns an object with behaviour I don't understand,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47780884/

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