假设我有一个返回承诺的函数foo
。是否有一种方法可以调用该函数,并且只有在未解决拒绝的情况下,才可以选择Promise.prototype.catch
来调用该函数?我想要一个在node.js和浏览器中都能使用的解决方案。例如:
const fooResult = foo();
// pass fooResult somewhere else where fooResult may be caught with catch
catchIfUncaught(fooResult, (err) => {
console.log(err); // should be foo rejection only if the rejection is not caught elsewhere
// no unhandled rejection occurs
});
答案 0 :(得分:1)
不,没有。当您的函数返回一个Promise时,错误处理留给了调用者-如果他错过了,他将得到一个unhandledpromiserejection
事件。
我能想象的唯一破解方法是识别then
调用,然后取消自己的错误处理:
function catchIfUncaught(promise, handler) {
let handled = false;
promise.catch(err => {
if (!handled)
handler(err);
});
promise.then = function(onFulfilled, onRejected) {
handled = true;
return Promise.prototype.then.call(this, onFulfilled, onRejected);
};
return promise;
}
示例:
catchIfUncaught(Promise.reject(), err => console.log("default handler", err));
catchIfUncaught(Promise.reject(), err => console.log("default handler", err))
.catch(err => console.log("catch handler", err));
catchIfUncaught(Promise.reject(), err => console.log("default handler", err))
.then(null, err => console.log("then rejection handler", err));
catchIfUncaught(Promise.reject(), err => console.log("default handler", err))
.then(res => {})
.catch(err => console.log("chained catch handler", err));
catchIfUncaught(Promise.reject(), err => console.log("default handler", err))
.then(res => {});
// unhandled rejection (on the chained promise)
如您所见,这仅在函数的调用者完全忽略结果时才有用-的确很少见。如果他愿意,我建议您仍然let the caller handle errors。
A similar hack I devised earlier将使用handler
作为onRejected
的默认值:
…
promise.then = function(onFulfilled, onRejected = handler) {
// ^^^^^^^^^
return Promise.prototype.then.call(this, onFulfilled, onRejected);
};
这将在catchIfUncaught(…).then(res => …);
情况下激活默认处理程序,但在较长的链中可能与调用方有很强的直觉。
还要注意,这两种骇客都无法与await
一起正常工作,它们总是导致呼叫者需要捕获的异常。同样,对于任何其他期望有可能实现的内置函数-它们总是使用两个参数调用.then
。
答案 1 :(得分:0)
你可以看看这个包https://npmjs.org/package/e-promises
但是您必须更改代码才能使用新机制
EPromise
YourPromise extends EPromise
(可选)扩展它YourPromise.prototype.unchaught
分配给您的 catchIfUncaught
实现foo
中的代码,每个做出承诺的地方都必须更改为使用YourPromise
等new YourPromise(executor) / YourPromise.resolve / YourPromise.all / ...
答案 2 :(得分:-1)
如果您不关心传递的情况,则可以捕获错误情况。
catchIfUncaught.catch(function (err) {
console.error('We had an error: ', err)
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch