为什么“shouldNotResolve”方法没有捕获被拒绝的承诺?

时间:2017-06-22 07:32:46

标签: javascript promise es6-promise

我希望a.shouldNotResolve()会抓住' a.cancelOrder中被拒绝的承诺,并且返回'期望这可以捕获',而是它结算,返回'承诺无论如何已经解决了。

const a = {

  cancelOrder: function(){
    return Promise.reject('something broke')
    .then((x) => {
      return x;
    })
    .catch((e) => {
      console.log('this caught the error', e);
    });
  },

  shouldNotResolve: function() {
    return this.cancelOrder()
    .then(() => {
      console.log('promise resolved anyway');
    })
    .catch(() => {
      console.log('expected this to catch');
    });
  }
}

a.shouldNotResolve(); // "promise resolved anyway"

为什么a.cancelOrder会拒绝,但是a.shouldNotResolve会解决?

谢谢。

3 个答案:

答案 0 :(得分:1)

因为你在

中发现了这个错误
  cancelOrder: function(){
    return Promise.reject('something broke')
    .then((x) => {
      return x;
    })
    .catch((e) => { // <-- this catches all errors
      console.log('this caught the error', e);
    });
  },
对于承诺,

catch就像try-catch一样。如果你已经发现异常,那么外面就不会抓到。

&#13;
&#13;
try { 
  try {
    throw new Error('Failed')
  } catch(e) { // first catch
    console.log('inner', e.message)
  }

} catch(e) { // second catch
  console.log('outer', e.message)
}
&#13;
&#13;
&#13;

正如@robertklep暗示你可能想要重新抛出

  cancelOrder: function(){
    return Promise.reject('something broke')
    .then((x) => {
      return x;
    })
    .catch((e) => { // <-- this catches all errors
      console.log('this caught the error', e);
      return Promise.reject(e) // re-reject
    });
  },

&#13;
&#13;
const rejected1 = Promise.reject(1)

const resolved = rejected1
  .catch(x => console.log(x))
  .then(() => console.log('resolved'))

const rejected2 = rejected1.catch(() => {
  console.log('caught but rethrow')
  return Promise.reject(2)
})

rejected2.catch(x => console.log(x))
&#13;
&#13;
&#13;

答案 1 :(得分:0)

因为在cancelOrder函数中可以看到它已经在链中的早期(&#34; catched&#34;?)中被捕获了。如果你想在那里抓住但仍然通过链条拒绝,你需要再次扔掉它:

  cancelOrder: function(){
    return Promise.reject('something broke')
    .then((x) => {
      return x;
    })
    .catch((e) => {
      console.log('this caught the error', e);
      throw e;
    });
  }

答案 2 :(得分:0)

在承诺流程之外的cancelOrder中写下catch,因此它不会将承诺恢复到成功状态。

const a = {

  cancelOrder: function(){
    const result = Promise.reject('something broke')
      .then((x) => {
        return x;
      });

    result.catch((e) => {
      console.log('this caught the error', e);
    });

    return result;
  },

  shouldNotResolve: function() {
    return this.cancelOrder()
    .then(() => {
      console.log('promise resolved anyway');
    })
    .catch(() => {
      console.log('expected this to catch');
    });
  }
}

正如另一个答案中所提到的,如果你想将catch放在promise流中,另一个选择就是重新抛出错误。

你也可以考虑编写一个为你做这个的拦截器:

function doCatch(fn) {
  return function(reason) {
    fn(reason);
    throw reason;
  });
}

现在你可以写

  cancelOrder: function(){
    return Promise.reject('something broke')
      .then((x) => {
        return x;
      })
      .catch(doCatch(err => console.err("this caught the error", e)));
  }

顺便说一下,.then((x) => { return x; })是无操作。