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));
答案 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