在try / catch块中包装一个promise是正确的方法吗?

时间:2016-08-07 02:11:38

标签: javascript promise

我有一个调用承诺的函数。在成功或失败时,我想返回一些超出承诺返回的数据。

我认为这可行:

function foo() {
  const extra = 'bar'
  return thepromise().then((res) => {
    return {
      result: res,
      data: extra
    }
  }, (err) => {
    // this will not happen if an error is thrown in the called promise
    return {
      result: res,
      data: extra
    }
  })
}

foo().then((res) => { }, (err) => { // error result ends up here })

然而,这不起作用。如果在thepromise中抛出错误,它将不会调用catch块,而是调用foo()的catch块。

处理此问题的正确方法是什么?我使用try / catch块成功,但我不确定这是最好的方法:

function foo() {
  const extra = 'bar'
  return new Promise((resolve, reject) => {
    try {
      return thepromise(p)
    } catch (e) {
      reject(e)
    }
  })
  .then(function(res) {
    return {
      result: res,
      data: extra,
      status: 'success'
    }
  }, function(err) {
    return {
      result: err,
      data: extra
      status: 'error'
    }
  })
}

3 个答案:

答案 0 :(得分:1)

任何用于返回promise的函数都不应该抛出任何异常或错误。

如果确实如此,那应该被认为是错误的。

要修复错误的方法,而不是抛出异常,请拒绝返回的promise。

有时您无法修复底层错误,例如当您使用其他人的API时。如果是这种情况,首先要做的最重要的事情是向原作者报告错误,以便解决潜在的问题。

报告问题后,您可以将错误方法包装在一个简单的实用程序中来解决问题:

function fixBrokenPromise(promise/*, args...*/) {
  var args = Array.prototype.slice.call(arguments, 1),
      ret;
  try {
    ret = promise.apply(null, args);
  } catch (ex) {
    ret = Promise.reject(ex);
  }
  return ret;
}

这可以称为:

fixBrokenPromise(thepromise/*, args you want to pass to thepromise */)
  .then(...resolve...,
        ...reject...);

答案 1 :(得分:0)

如果您愿意接受Promises的扩展程序,bluebirdtry method可以满足您的需求:

import Promise from 'bluebird';

// ...

return Promise
  .try(thepromise)
  .then(res => ({
    result: res,
    data: extra
  })
  .catch(err => ({
    result: res,
    data: extra
  });

答案 2 :(得分:0)

该错误被视为在.catch()处理,这将返回已解锁的链接.then()的承诺。您可以将throw错误发送到下一个.catch()



function foo() {
  const extra = 'bar'
  return thepromise().then((res) => {
    return {
      result: res,
      data: extra
    }
  }, (err) => {
    throw new Error(JSON.stringify({
      result: err || "no rejection reason provided",
      data: extra
    }))
  })
}

var thepromise = () => Promise.reject();

foo().then(data => console.log("fulfilled", data))
.catch(err => console.log("catch", JSON.parse(err.message)))