在Promise中混淆错误和拒绝

时间:2016-02-09 02:11:15

标签: 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){
    })

令我困惑的是:

  1. 当函数(错误)被调用时以及何时调用catch?
  2. 如何在then中解决和拒绝?
  3. 由于

3 个答案:

答案 0 :(得分:13)

使用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中的任何错误都没有被捕获。

答案 1 :(得分:6)

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

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

如果Promise拒绝,你的第一个.then()中的第二个函数将被拒绝的值调用,并且它返回的将成为一个新的已解析的Promise,它将进入第一个函数然后你的第二个。 Catch也从未被称为。只有当Promise拒绝并且你继续拒绝承诺或在你的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),如果在第一个函数中发生错误,它就不会被第二个函数捕获:一些后来链接在方法上的东西必须抓住它。

答案 2 :(得分:3)

  1. 请注意

    中的示例执行程序函数

    var p = new Promise(function(res, rej){});

    不完整。提供给Promise构造函数的实际执行函数必须调用其第一个参数(res)来解析构造的promise,或者它的第二个参数(rej)来拒绝promise。这些通话通常是异步进行的,但不一定要在ES6中。

  2. 使用Promise对象(或任何具有.then属性的对象解析promise)时,在分辨率本身提供的promise对象变为 拒绝。已完成的值会传递给.then onFulfilled个处理程序,被拒绝的值会传递给.then onRejected个处理程序/侦听器/回调(取决于您的术语)。

  3. 但是当使用非promise(如)对象解析promise时,将使用分辨率值调用作为.then的第一个参数提供的侦听器。

  4. 当使用任何值拒绝承诺时,将使用被拒绝的值调用作为.then的第二个参数或.catch的第一个参数提供的侦听器。

    < / LI>
  5. .catch是使用提供的参数作为第二个参数调用.then并省略第一个参数的委婉说法,如

    Promise.prototype.catch = function( listener) { return this.then(null, listener);};

  6. .then注册onFulfillonReject功能的行为相同。拒绝链式承诺会引发错误。履行链式承诺会返回非承诺值。持有链式承诺会返回一个承诺(或承诺)对象。

  7. (更新)当提供给.then( onFulfill, onReject)的参数缺失或不是函数对象时,处理等同于从以下位置提供虚拟函数:

    function onFulfill( data) { return data;}
    function onReject( err) { throw err;}
    

    通过一个参数调用thencatch时,这是常见的情况。