在Promise中混淆错误和拒绝

Kua*_*uan 14 javascript promise

所有:

我对JS Promise很陌生,在Promise链接方面有一个令人困惑的地方,比如说我有一个像以下链接的承诺:

var p = new Promise(function(res, rej){
})
.then(
    function(data){
    }, 
    function(err){
    })
.then(
    function(data){
    }, 
    function(err){
    })
.catch(
    function(err){
    })
Run Code Online (Sandbox Code Playgroud)

让我困惑的是:

  1. 当调用函数(错误)和调用catch时?
  2. 如何解决和拒绝then

谢谢

rab*_*tco 13

使用Promise的公式是:

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

  var condition = doSomething();

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

});
Run Code Online (Sandbox Code Playgroud)

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

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

有关更详细的说明,请参阅:Javascript Promises - There and Back.


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

实际上,您可以将自己限制.catch.then链的末端的拒绝回调.任何Error在任何.then将会落到.catch.但有一个微妙之处:.catch没有发现任何错误.


Dti*_*son 6

重要的是要知道.then()方法总是链接 Promise上,它返回一个新的 Promise,其值和解析/拒绝状态基于给它返回的函数.

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

如果Promise拒绝,你的第一个.then()中的第二个函数将被拒绝的值调用,并且它返回的任何将成为一个新的已解析的Promise,它将传递到你的第二个函数中.Catch也从未被称为.只有当Promise拒绝并且你继续返回被拒绝的Promises或function(err){}function(err){}在你的catch 函数抛出错误时才会被调用.

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

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

一般来说,在同一个.then()中定义已解析和被拒绝的路径并不明智:PROMISE.then(fn).catch(fn)更安全/更清晰的做法,因为第一个.then()中的任何错误都将被catch捕获.PROMISE.then(fn, fn)但是,如果你这样做,如果在第一个函数中发生错误,它将不会被第二个函数捕获:一些后来链接在方法上的一些必须捕获它.