我看了一下bluebird承诺常见问题,其中提到。then(成功,失败)是一个反模式。我不太明白它对试捕的解释。 下面有什么问题吗?

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) })

有什么不同?


当前回答

Using .then().catch() lets you enable Promise Chaining which is required to fulfil a workflow. You may need to read some information from database then you want to pass it to an async API then you want to manipulate the response. You may want to push the response back into the database. Handling all these workflows with your concept is doable but very hard to manage. The better solution will be then().then().then().then().catch() which receives all errors in just once catch and lets you keep the maintainability of the code.

其他回答

使用then()和catch()有助于连接promise上的成功和失败处理程序。catch()对then()返回的promise有效。它处理,

如果承诺被拒绝。见图中的第三条 如果在then()的成功处理程序中发生错误,则在下面的行号4到7之间。看到# 2。图片中的A (then()上的失败回调不会处理这个。) 如果在then()的失败处理程序中发生错误,则下面的第8行。看到# 3。B在照片上。

1. let promiseRef: Promise = this。aTimetakingTask(假); 2. promiseRef 3 .不要犹豫( 4. (result) => { 5. /*成功,决心承诺。 6. 在这里处理数据*/ 7. }, 8. (error) => console.log(error) 9)。 10. .catch((e) => { 11. /*成功,决心承诺。 12. 在这里处理数据*/ 13. });

注意:很多时候,如果catch()是,则可能没有定义失败处理程序 已经写的。 EDIT: reject()只会在出现错误时调用catch() then()中的处理程序没有定义。注意图片中的第三条 问题()。当第8行和第9行中的处理程序没有被调用时,将调用它 定义的。

这是有意义的,因为如果由回调处理,那么then()返回的promise不会有错误。

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

但我相信你链接到的文本的观点是,然后是最有用的,而不是回调在它的能力链一堆异步步骤,当你实际上这样做,然后的2参数形式微妙地不像预期的那样表现,出于上述原因。当使用中链时,这尤其违反直觉。

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

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

捕捉方法

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

优势

所有错误都由一个catch块处理。 Even捕获then块中的任何异常。 多个成功回调的链接

缺点

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

成功/错误的方法

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

优势

你得到了细粒度的错误控制。 你可以使用常见的错误处理功能来处理各种类型的错误,比如db错误,500错误等等。

Disavantages

如果希望处理成功回调抛出的错误,仍然需要另一个catch

简单的解释:

在ES2018

当使用参数onRejected调用catch方法时, 采取以下步骤: 让承诺成为这份价值。 回报呢?Invoke(promise, "then",«undefined, onRejected»)。

这意味着:

promise.then(f1).catch(f2)

=

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

好例子,而不是文字。以下代码(如果第一个承诺已解决):

Promise.resolve()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

等于:

Promise.resolve()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)

但与被拒绝的第一个承诺不同,这是不一样的:

Promise.reject()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

Promise.reject()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)