【问题标题】:Are jquery deferred callbacks synchronous if the deferred is already resolved?如果延迟已经解决,jquery延迟回调是否同步?
【发布时间】:2014-05-03 05:33:37
【问题描述】:

我猜答案是肯定的,但密码不是最容易破译的。在docs 它说

使用 deferred.then()、deferred.always()、deferred.done() 或 deferred.fail() 添加到对象的任何回调都将排队等待稍后执行。调用 deferred.resolve() 或 deferred.resolveWith() 将 Deferred 转换为已解决状态并立即执行任何设置的 doneCallbacks。

但这并没有明确涵盖将回调附加到已解决的 Deferred 的情况。

【问题讨论】:

    标签: jquery asynchronous promise jquery-deferred


    【解决方案1】:

    如果承诺已经解决/拒绝,新的回调将同步执行。

    来自jQuery.deferred() doc

    一旦对象进入已解决或已拒绝状态,它就会保持该状态。回调仍然可以添加到已解决或已拒绝的 Deferred 中——它们将立即执行。

    演示(Fiddle):

    var def = jQuery.Deferred(),
        promise = def.promise();
    console.log('before 1');
    promise.done(function () {
        console.log('done 1');
    });
    console.log('after 1');
    def.resolve();
    console.log('before 2');
    promise.done(function () {
        console.log('done 2');
    });
    console.log('after 2');
    

    输出:

    1
    1后
    完成 1
    2之前
    完成 2
    2 后

    【讨论】:

    • 请注意,这是 jQuery 承诺不遵循 Promises/A+ specs 的那些方面之一。 AFAIK,QBluebird 实现都将确保回调异步执行(例如通过setImmediate)。
    • @Noseratio - 有趣。我正在考虑改用 Bluebird,但这种行为实际上会让我更难实现某些功能
    • @wheresrhys 我看不出具有确定性执行顺序而不是随机执行顺序如何使任何功能的实现变得更加困难
    • @wheresrhys bluebird 实际上有一个构建(适当地称为 Zalgo)来执行此操作。你真的真的不想这样做。它可以产生真正“有趣”的错误。
    • @wheresrhys 唯一的区别是您可以保证一定的执行顺序,而对于像 jQuery 这样的实现则不能保证执行顺序。所以说这样的保证使某些事情更难实现是荒谬的。
    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2014-03-11
    相关资源
    最近更新 更多