首页 文章

在Promise中混淆错误和拒绝

提问于
浏览
14

所有:

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

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

让我困惑的是:

  • 当调用函数(错误)并调用catch时?

  • 如何解决和拒绝 then

谢谢

3 回答

  • 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 无法解析无关 .

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

  • 6

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

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

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

    要解决 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) ,如果在第一个函数中发生错误,它将不会被第二个函数捕获:一些后来链接的方法必须捕获它 .

  • 3
    • 注意示例执行程序函数

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

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

    • 当使用Promise对象(或具有 .then 属性的任何对象作为函数)解析promise时,在分辨率本身提供的promise对象变为 fulfilledrejected 之前不会发生任何事情 . 已完成的值将传递给 .then onFulfilled 处理程序,被拒绝的值将传递给 .then onRejected 处理程序/侦听器/回调(取决于您的术语) .

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

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

    • .catch 是用提供的参数作为第二个参数调用 .then 并省略第一个参数的委婉说法,如

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

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

    • (更新)当提供给 .then( onFulfill, onReject) 的参数缺失或不是函数对象时,处理相当于从以下位置提供虚函数:
    function onFulfill( data) { return data;}
    function onReject( err) { throw err;}
    

    这是通过单个参数调用 thencatch 时的常见情况 .

相关问题