我写了一些荒谬简单的错误处理代码,它可以完美地运行同步操作。我不得不修改throwError
函数以表现我想要的异步操作,但现在它不能像我期望的同步操作那样工作。如何检测是否在Promise的catch块中调用函数以改变行为?
这是适用于同步操作的代码:
const errorHandler = () => console.log('Woot, handled error')
const throwError = (error) => {
throw error
}
try {
throwError(new Error('Blah blah'))
console.log('This should not be reached')
} catch(error) {
errorHandler(error)
}
这是非常适合异步操作的代码:
const errorHandler = () => console.log('Blah blah')
const throwError = (error) => {
errorHandler(error)
}
const loadStuff = () => new Promise((_, reject) => {
console.log('Loading stuff')
setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
})
try {
loadStuff().catch(throwError)
} catch(error) {
errorHandler(error)
}
但是如果你将异步throwError
代码放在同步代码中,第二个console.log就会执行。如果将同步throwError
放在异步代码中,则会产生无人承诺拒绝错误。
如果只有一个throwError
函数,我怎么能知道它是捕获一个Promise还是被手动调用直接调用errorHandler
和throw
ing错误之间切换?假设只有throwError
和最后一个catch
条款可以访问errorHandler
。
由于某些原因,这个问题很难写,可能措辞很奇怪,我很欣赏任何澄清的编辑。
问题:
但是如果你在同步代码中放入async throwError代码,第二个console.log就会执行。如果将sync throw错误放在异步代码中,则会产生无法拒绝的承诺拒绝错误。
这可能是事先应该澄清的一些事情,你编写的两个函数throwError做了完全不同的事情,因为一个人收到错误并抛出它,而另一个只记录'Blah blah'。
另一方面在代码中
const errorHandler = () => console.log('Blah blah')
const throwError = (error) => {
errorHandler(error)
}
const loadStuff = () => new Promise((_, reject) => {
console.log('Loading stuff')
setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
})
try {
loadStuff().catch(throwError)
} catch(error) {
errorHandler(error)
}
如果我们将throwError函数更改为与第一个函数相同,那么代码将如下所示:
const errorHandler = () => console.log('Blah blah')
const throwError = (error) => {
throw error
}
const loadStuff = () => new Promise((_, reject) => {
console.log('Loading stuff')
setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
})
try {
loadStuff().catch(throwError)
} catch(error) {
errorHandler(error)
}
这里发生的是,一旦loadStuff被拒绝,那么执行throwError函数就会抛出错误,但是它不会被try / catch语句捕获,因为try中的语句不会像loadStuff那样抛出错误返回一个promise,loadStuff的catch中发生的事情与try / catch的catch没有任何关系,因为它有一个不同的scope。事实上,如果这样写的话,两个捕获都可以同时执行:
const errorHandler = () => console.log('Blah blah')
const throwError = (error) => {
console.log('another catch')
throw error
}
const loadStuff = () => new Promise((_, reject) => {
console.log('Loading stuff')
setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
})
try {
loadStuff().catch(throwError)
throw new Error('my Error')
} catch(error) {
errorHandler(error)
}
说完并假设每次抛出一个错误你想要以同样的方式处理它,就像这样写它:
const errorHandler = () => console.log('Blah blah')
const loadStuff = () => new Promise((_, reject) => {
console.log('Loading stuff')
setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
})
try {
loadStuff().catch(errorHandler)
} catch(error) {
errorHandler(error)
}