Why would you try-catch around a promise? Does that catch the promise's error?

时间:2017-04-30 02:04:43

标签: javascript ecmascript-6 promise es6-promise

I stumbled upon some code that looked off to me:

try {
  somePromise()
    .then(res => console.log(res));
} catch (err) {
  console.error(err);
}

If some somePromise() fails, would this not get caught, and the app would crash? Does this try-catch even do anything?

Should be this, correct?:

  somePromise()
    .then(res => console.log(res))
    .catch(err => console.error(err));

2 个答案:

答案 0 :(得分:4)

TL; DR - 如果返回promise的函数在返回promise之前抛出异常,那么该异常必须在常规的try-catch块中捕获。

考虑这个功能

function asyncAdd(x,y){
   if(x === 2){
        throw new Error("good old exception")
   }else if(x === 1) { 
      return Promise.reject("fancy exception")
   }

   return Promise.resolve(x+y)
}

这会打印出“尝试抓好旧例外”

try{
  asyncAdd(2,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
  console.error("Try caught", e);
}

这将打印出“承诺被捕获的奇特异常”

try{
  asyncAdd(1,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
  console.error("Try caught", e);
}

答案 1 :(得分:2)

如果您正在处理可能返回Promise 抛出错误的垃圾函数,那真的很不幸。我建议使用下面的通用tryCatch实用程序来处理攻击性功能。

const badFunction = x =>
{ if (x)
    return Promise.resolve(x)
  else
    throw Error('this is a bad function')
}

const tryCatch = f => x =>
{ try
  { return Promise.resolve(f(x)) }
  catch (err)
  { return Promise.reject(err) }
}

tryCatch(badFunction)(1).then(console.log, console.error)
// 1

tryCatch(badFunction)(0).then(console.log, console.error)
// Error: this is a shit function

如果可以,请修复

如果你的垃圾功能在你的控制范围内,那么我会建议写这样的东西

const goodFunction = x =>
{ if (x)
    return Promise.resolve(x)
  else
    return Promise.reject(Error('this is a good function'))
}

goodFunction(1).then(console.log, console.error)
// 1

goodFunction(0).then(console.log, console.error)
// Error: this is a good function

.then中的未捕获错误 - 链接功能

这并不是说有时我们仍然可能遇到需要使用可能抛出的函数的情况。例如,如果我们then一个可以抛出的函数 - 在这种情况下JSON.parse - Promises已经具备了以方便的方式处理它的功能;抛出的错误将被捕获在被拒绝的承诺

const goodFunction = x =>
  Promise.resolve(x)
  
goodFunction('"abc"')
  .then(JSON.parse)
  .then(console.log, console.error)
  // 'abc'

goodFunction('abc')
  .then(JSON.parse)
  .then(console.log, console.error)
  // 'Unexpected token a in JSON at position 0'

Promise执行者中未捕获的错误

下面我们进行疏忽,我们称之为可以抛弃Promise执行者的函数。一般来说,我认为最好在执行程序中显式编写try/catch并使用抛出的错误调用reject。然而,Promise也在这种情况下退缩了;它将自动捕获抛出的错误并将其包装在被拒绝的承诺中。

const okFunction = x =>
  new Promise(resolve => resolve(JSON.parse(x)))

okFunction('"abc"').then(console.log, console.error)
// 'abc'

okFunction('abc').then(console.log, console.error)
// Error: Unexpected token a in JSON at position 0