【问题标题】:When to Use deferred.reject()?何时使用 deferred.reject()?
【发布时间】:2014-12-03 22:05:23
【问题描述】:

我很困惑何时使用deferred.resolve()deferred.reject()

快速示例

var doSomething = function() {

    var deferred = $.Deferred();

    if ( typeof myVar === "object" ) {

        // Do something with myVar - Start.

            deferred.resolve();

        // Do something with myVar - End.

    } else {

        // myVar isn't an object, but the function has finished executing
        // and that's what I want to know.
        // With reject() I'll be forced to use always() instead of done()
        // because there'll be also a fail() method available if myVar
        // is not an object.
        deferred.reject();
    }

    return deferred.promise();
};

问题

关于何时应该使用 deferred.reject() 的任何提示或规则?

注意

myVar 在某些时候是动画的。动画完成后,我会做一些其他事情,然后才解决 Deferred 对象。

【问题讨论】:

  • 通知您的应用 myVar 检查失败
  • 解决就是成功,拒绝就是失败。您应该将延迟用于异步处理,而不是人为的同步示例。您基本上是在说您期望或希望会发生某些事情,但不能保证它会发生,因此您需要处理任何一个选项。网络上有大量可用信息,jquery 文档看起来确实很薄,但一般来说,查找 deferreds/promises/futures 应该会为您提供所需的信息。

标签: jquery jquery-deferred


【解决方案1】:

.resolve().reject() 是您的承诺结果的两个不同可能分支。

不过,如何最好地使用这两种可能的路径,真正取决于程序员,.resolve(data) 通常用于成功的结果,并可选择返回带有成功结果的数据,.reject(err) 通常用于错误情况和返回有关错误的一些信息。

您使用哪个决定了在.then(f1, f2) 上为此promise 触发哪些回调。如果使用.resolve(),则调用f1(假设为成功处理回调)。如果使用.reject(),则调用f2(假设为错误处理回调)。


还有一些更高级别的函数在 Promise 上运行,例如 $.when()(在 jQuery 世界中)假设 .resolve() 是成功且 .reject() 是错误条件。 $.when() 在所有承诺都已解决或任何承诺被拒绝(假设是错误条件)时调用它的回调。


如果调用代码只关心操作何时完成(无论是否成功完成),那么您有三个不同的选项,选择哪个是您的选择:

1) 您可以使用.resolve().reject(),然后将您的完成处理程序放在一个函数中并像这样调用它:

doSomething.then(doneHandler, doneHandler);

2) 您可以使用.resolve().reject(),然后像这样使用.always()

doSomething.always(...);  

.always() 的一个缺点是它是一个 jQuery 特定的方法,而不是一个 Promise 标准,因此它可能会在未来发生变化。例如,Bluebird 和 Q Promise 库使用 .finally() 来实现此类功能。

3) 您可以将.resolve() 用于两条路径,因此无论它如何/为何完成,您都只有一个完成处理程序。

doSomething.then(fn);

前两个选项的优点是,在未来的某个时候,调用者可以更轻松地实现成功完成与错误完成的不同行为。

第三个选项的优点是,您可以更轻松地将此承诺与 $.when() 之类的东西一起使用,以了解何时完成以及其他一些事情。


在查看您的特定代码时,您应该记住,当您有异步操作(例如 ajax 调用)时,最好使用 Promise。如果您没有任何异步操作,那么您也可以直接从函数中返回一个值来指示成功或失败,并让调用代码检查该错误并根据该错误进行分支。使用 Promise 并不像用于同步活动的普通程序代码(例如您问题中的示例代码)那么简单,因此通常没有充分的理由将 Promise 用于纯同步编码。

【讨论】:

  • 我不能只返回一个值,因为 myVar 在某些时候是动画的。
  • @user557108 - 好的,您只是没有显示任何异步内容,所以我不确定。无论如何,如果您不关心错误情况并且您只关心操作何时完成(无论是否由于错误而提前完成),那么您可以只使用 .resolve() 为您的路径,然后需要只有一个完成处理程序。这真的取决于你。将所有内容都推送到一个.resolve() 路径中,如果您希望在将来的某个时间将成功处理与错误处理区分开来,将会变得更加困难。或者,您可以使用resolve 和reject,然后使用.always()
  • @user557108 - 为我对不同选项的回答添加了更多解释。
猜你喜欢
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 2015-09-30
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 1970-01-01
相关资源
最近更新 更多