混淆 error 和 reject in Promise

新手上路,请多包涵

全部:

我是 JS Promise 的新手,在谈到 Promise 链接时有一个混淆,假设我有一个像这样的 Promise 链接:

 var p = new Promise(function(res, rej){
})
.then(
    function(data){
    },
    function(err){
    })
.then(
    function(data){
    },
    function(err){
    })
.catch(
    function(err){
    })

是什么让我困惑:

  1. 什么时候调用 function(err) 和什么时候调用 catch?
  2. 如何解决和拒绝 then

谢谢

原文由 Kuan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 274
2 个回答

使用 Promise 的公式是:

 var p = new Promise(function(resolve, reject) {

  var condition = doSomething();

  if (condition) {
    resolve(data);
  } else {
    reject(err);
  }

});

.catch 没有什么特别的,它只是 .then (undefined, func) 的糖,但是 .catch 更清楚地表明它纯粹是一个错误处理程序。

如果 Promise 没有解决并且其中没有提供拒绝回调,它会跳到链中的下一个 .then 中有一个拒绝回调。拒绝回调是 reject(err)

有关更详细的解释,请参阅: Javascript Promises - There and Back again


那就是:在你的例子中。 catch 只有在前面的拒绝回调有错误时才会被调用。那就是 reject(err) 函数本身有错误 - 这与前面的 Promise 没有解决无关。

您基本上可以将自己限制在 .catch.then 链的末端的拒绝回调。任何 Error 在任何 .then 将落入 .catch 。不过有一个微妙之处: .catch 中的任何错误都不会被捕获。

原文由 rabbitco 发布,翻译遵循 CC BY-SA 3.0 许可协议

需要知道的重要一点是 .then() 方法总是链接 _到一个 Promise 上_,并且它返回一个 新的 Promise,其值和已解决/拒绝的状态基于返回给它的函数。

在您的示例中,如果原始 Promise 解析,那么您的第一个 .then() 中的第一个函数将使用解析后的值进行调用。如果它返回一个值,那么 返回的任何值最终都会传递给 第二个.then() 中的第一个函数。 catch 中的函数永远不会被调用。

如果 Promise 拒绝,您的第一个 .then() 中的第二个函数将使用被拒绝的值调用,并且无论它返回什么 都将成为一个新的已解决的 Promise,它传递给您的第二个 then 的第一个函数。 Catch 也从不在这里调用。只有当 Promise 拒绝并且您 不断返回被拒绝的 Promises 或在您的 function(err){} 函数中抛出错误时, 您才会在调用的 catch 块中获得 function(err){}

要在您的 function(data){} 函数中解析,您需要做的就是返回一个值(或返回一个稍后解析的 Promise/thenable)。要拒绝,您需要抛出错误,实际 导致 错误,返回最终拒绝的新 Promise,或者显式返回 Promise.reject(::some value::)

要在您的 function(err){} 块中解析,您需要做的就是返回一个新值。您还可以返回一个 Promise,在这种情况下,Promise 将被返回(最终解决或拒绝)。

一般来说,在同一个 .then() 中同时定义已解决和被拒绝的路径是不明智的: PROMISE.then(fn).catch(fn) 是一种更安全/更清晰的做法,因为第一个 .then() 中的任何错误都会被抓到。但是,如果您执行 PROMISE.then(fn, fn) 而不是,如果第一个函数发生错误,第二个函数将不会捕获它:某些稍后链接的方法必须捕获它。

原文由 Dtipson 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题