有没有一种方法可以检测是否未兑现被拒绝的承诺? [英] Is there a way detect if a rejected promise is unhandled?
问题描述
假设我有一个函数 foo
,该函数返回一个诺言。是否有一种方法可以调用该函数,并且只有在未拒绝拒绝的情况下,才可以选择 Promise.prototype.catch
结果?我想要一个在node.js和浏览器中都能使用的解决方案。例如:
Let’s say I have a function foo
which returns a promise. Is there a way to call the function, and optionally Promise.prototype.catch
the result only if its rejection is unhandled? I want a solution which works in both node.js and the browser. For example:
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
});
推荐答案
不,没有。当您的函数返回一个Promise时,错误处理留给了调用者-如果他错过了,他将得到一个 unhandledpromiserejection
事件。
No, there is not. When your function returns a promise, that leaves error handling to the caller - and he'll get an unhandledpromiserejection
event if he misses to do that.
我能想象的唯一破解方法是先识别然后
个呼叫,然后取消自己的呼叫错误处理:
The only hack I can imagine would be to recognise then
calls, and then cancel your own error handling:
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)
如您所见,这是仅在函数的调用者完全忽略结果时才有用-这确实很少见。如果是的话,我建议您仍然让呼叫者处理错误。
As you can see, this is only useful when the caller of your function completely ignores the result - which is really uncommon. And if he does, I'd recommend to still let the caller handle errors.
我之前设计的类似骇客是使用 handler
作为 onRejected
的默认值:
A similar hack I devised earlier would be to use the handler
as the default for onRejected
:
…
promise.then = function(onFulfilled, onRejected = handler) {
// ^^^^^^^^^
return Promise.prototype.then.call(this, onFulfilled, onRejected);
};
这将激活 catchIfUncaught(...)中的默认处理程序。 res =>…);
的情况,但对于较长链中的调用方来说可能很违反直觉。
This would activate the default handler in the catchIfUncaught(…).then(res => …);
case, but probably be highly counter-intuitive to the caller in longer chains.
也请注意,这两个黑客与 await
一起可以正常工作,它们总是导致呼叫者需要捕获的异常。并且对于任何其他期望有可能实现的内置函数来说,它们都是相同的-他们总是使用两个参数调用。然后
。
Also notice that neither of these two hacks work properly together with await
, where they always lead to an exception that the caller needs to catch. And same for any other builtin that expects a thenable - they always call .then
with two arguments.
这篇关于有没有一种方法可以检测是否未兑现被拒绝的承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!