首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候.then(成功,失败)被认为是promises的反模式?

什么时候.then(成功,失败)被认为是promises的反模式?
EN

Stack Overflow用户
提问于 2014-07-10 03:31:00
回答 7查看 27.8K关注 0票数 215

我看过bluebird promise FAQ,里面提到了.then(success, fail) is an antipattern。对于trycatch,我不太理解它的解释。以下内容有什么问题?

代码语言:javascript
复制
some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })

这个例子似乎表明下面的方法是正确的。

代码语言:javascript
复制
some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })

有什么关系呢?

EN

回答 7

Stack Overflow用户

发布于 2014-07-10 04:35:03

有什么区别?

.then()调用将返回一个promise,如果回调抛出错误,该promise将被拒绝。这意味着,当成功的logger失败时,错误将传递给下面的.catch()回调,但不会传递给success附带的fail回调。

这是一个控制流图:

要在同步代码中表示它:

代码语言:javascript
复制
// some_promise_call().then(logger.log, logger.log)
then: {
    try {
        var results = some_call();
    } catch(e) {
        logger.log(e);
        break then;
    } // else
        logger.log(results);
}

第二个log (类似于.then()的第一个参数)将仅在未发生异常的情况下执行。带标签的代码块和break语句感觉有点奇怪,这实际上就是python has try-except-else for (推荐阅读!)

代码语言:javascript
复制
// some_promise_call().then(logger.log).catch(logger.log)
try {
    var results = some_call();
    logger.log(results);
} catch(e) {
    logger.log(e);
}

catch记录器还将处理来自成功记录器调用的异常。

不同之处到此为止。

我不太明白它对try and catch的解释

理由是,通常,您希望在处理的每个步骤中捕获错误,并且您不应该在链中使用它。期望您只有一个处理所有错误的最终处理程序-而当您使用“反模式”时,一些then回调中的错误不会被处理。

然而,这个模式实际上非常有用:当你想要处理在这一步中发生的错误,并且你想要在没有错误发生时做一些完全不同的事情--即当错误是不可恢复的时候。请注意,this is branching control flow。当然,这有时也是我们所期望的。

以下内容有什么问题?

some_promise_call() .then(function(res) { logger.log(res) },function(err) { logger.log(err) })

你不得不重复你的回电。你更想要

代码语言:javascript
复制
some_promise_call()
   .catch(function(e) {
       return e; // it's OK, we'll just log it
   })
   .done(function(res) {
       logger.log(res);
   });

为此,您还可以考虑使用.finally()

票数 244
EN

Stack Overflow用户

发布于 2014-07-10 04:30:19

这两者并不完全相同。不同之处在于,第一个示例不会捕获在success处理程序中抛出的异常。因此,如果您的方法应该只返回已解析的promises (通常是这种情况),则需要一个尾随的catch处理程序(或另一个带有空success参数的then )。当然,您的then处理程序可能不会执行任何可能会失败的操作,在这种情况下,使用一个带有两个参数的then就可以了。

但我相信您链接的文本的要点是,与回调相比,then最有用的地方在于它能够链接一系列异步步骤,而当您实际执行此操作时,由于上述原因,then的双参数形式并不能巧妙地表现出预期的效果。当使用中链时,它特别违反直觉。

作为一个做了很多复杂的异步工作的人,我真的建议避免这种反模式,使用单独的处理程序方法。

票数 40
EN

Stack Overflow用户

发布于 2016-03-20 22:55:26

通过观察两者的优缺点,我们可以计算出哪一种适合这种情况。这是实现承诺的两种主要方法。两者各有优缺点

捕获方法

代码语言:javascript
复制
some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })

优势

  1. 所有错误都由一个catch块处理。
  2. 甚至可以捕获then block.
  3. Chaining of multiple success

中的任何异常

Disadvantages

  1. 在链接的情况下,很难显示不同的错误消息。

成功/错误方法

代码语言:javascript
复制
some_promise_call()
.then(function success(res) { logger.log(res) },
      function error(err) { logger.log(err) })

优势

  1. 您可以获得细粒度的错误控制。
  2. 您可以为各种类型的错误提供通用的错误处理函数,如数据库错误、500错误等。

Disavantages

  1. 如果您希望处理由成功回调

抛出的错误,则仍需要另一个catch

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24662289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档