.then(成功,失败)什么时候被视为承诺的反模式?

JavaScript Node.js

宝儿GO

2020-03-24

我看了蓝鸟诺言常见问题解答,其中提到这.then(success, fail)是一种反模式我对试捕一无所知。以下是什么问题?

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

似乎该示例建议以下是正确的方法。

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

有什么不同?

第3337篇《.then(成功,失败)什么时候被视为承诺的反模式?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

5个回答
Stafan小胖 2020.03.24

使用then()catch()帮助将成功和失败处理程序按承诺进行链接。catch()履行诺言返回的承诺then()它处理

  1. 如果诺言被拒绝。参见图片中的#3
  2. 如果then()的成功处理程序中发生错误,则在下面的第4到7行之间。请参阅图片中的#2.a(“失败回调” then()无法对此进行处理。)
  3. 如果then()的故障处理程序中发生错误,则下面的第8行。参见图片中的#3.b。

1. let promiseRef: Promise = this. aTimetakingTask (false); 2. promiseRef 3. .then( 4. (result) => { 5. /* successfully, resolved promise. 6. Work on data here */ 7. }, 8. (error) => console.log(error) 9. ) 10. .catch( (e) => { 11. /* successfully, resolved promise. 12. Work on data here */ 13. });

在此处输入图片说明

注意:很多时候,如果catch()已经编写了失败处理程序,则可能未定义编辑:reject()导致调用catch()只有在错误处理程序then()没有定义的。注意图片中的#3 catch()未定义第8行和第9行中的处理程序时将调用该方法。

这是有道理的,因为then()如果回调正在处理的话,promise返回的promise 不会出错。

Mandy 2020.03.24

使用.then().catch()使您可以启用完成工作流程所需的Promise Chaining您可能需要从数据库中读取一些信息,然后将其传递给异步API,然后才能处理响应。您可能需要将响应推回数据库。用您的概念来处理所有这些工作流是可行的,但很难管理。更好的解决方案是then().then().then().then().catch()一次捕获所有错误,并让您保持代码可维护性

GO 2020.03.24

简单说明一下:

在ES2018中

当使用参数onRejected调用catch方法时,将执行以下步骤:

  1. 让诺是这个价值。
  2. 返回?调用(承诺,“然后”,«未定义,onRejected»)。

这意味着:

promise.then(f1).catch(f2)

等于

promise.then(f1).then(undefiend, f2)
2020.03.24

通过查看两者的优缺点,我们可以对哪种情况适合进行计算得出猜测。这是实现承诺的两种主要方法。两者都有其优缺点

渔获法

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

优点

  1. 所有错误均由一个catch块处理。
  2. 甚至在then块中捕获任何异常。
  3. 链接多个成功回调

缺点

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

成功/错误方法

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

优点

  1. 您可以获得细粒度的错误控制。
  2. 您可以针对各种错误类别(例如db错误,500错误等)具有通用的错误处理功能。

破坏

  1. catch如果您希望处理成功回调引发的错误,则仍然需要另一个
泡芙 2020.03.24

两者并不完全相同。不同之处在于,第一个示例不会捕获success处理程序中引发的异常因此,如果您的方法仅应返回已解析的Promise(通常是这种情况),则需要一个尾随catch处理程序(或另一个then带有空success参数的处理程序)。当然,您的then处理程序可能不会做任何可能会失败的事情,在这种情况下,使用一个2参数then可能会很好。

但是我相信您链接到的文本的要点是,then与回调相比,它可以链接许多异步步骤,因此最有用,而且当您实际执行此操作时,2参数形式的then巧妙表现也不如预期的那样,由于上述原因。当使用中间链时,这尤其违反直觉。

作为做了很多复杂的异步工作并碰到这样的困境的人,我确实建议避免使用这种反模式,而应采用单独的处理程序方法,这比我想承认的要多。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android