有没有一种方法可以检测是否未兑现被拒绝的承诺? [英] Is there a way detect if a rejected promise is unhandled?

查看:51
本文介绍了有没有一种方法可以检测是否未兑现被拒绝的承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个函数 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆