Javascript 是否有办法检测被拒绝的承诺是否未得到处理?
假设我有一个函数Javascript 是否有办法检测被拒绝的承诺是否未得到处理?,javascript,node.js,promise,es6-promise,Javascript,Node.js,Promise,Es6 Promise,假设我有一个函数foo,它返回一个承诺。是否有方法调用该函数,并且可以选择Promise.prototype.catch仅在拒绝未处理时调用结果?我想要一个在node.js和浏览器中都能工作的解决方案。例如: const fooResult=foo(); //将fooResult传递到其他可能捕获fooResult的位置 catchIfUncaught(fooResult,(err)=>{ console.log(err);//仅当拒绝在别处未被捕获时才应为foo拒绝 //不会发生未经处理的拒绝
foo
,它返回一个承诺。是否有方法调用该函数,并且可以选择Promise.prototype.catch
仅在拒绝未处理时调用结果?我想要一个在node.js和浏览器中都能工作的解决方案。例如:
const fooResult=foo();
//将fooResult传递到其他可能捕获fooResult的位置
catchIfUncaught(fooResult,(err)=>{
console.log(err);//仅当拒绝在别处未被捕获时才应为foo拒绝
//不会发生未经处理的拒绝
});
如果您不关心传递的情况,您可以捕获错误情况
catchIfUncaught.catch(function (err) {
console.error('We had an error: ', err)
})
如果您不关心通过的情况,您可以捕获错误情况
catchIfUncaught.catch(function (err) {
console.error('We had an error: ', err)
})
不,没有。当您的函数返回一个承诺时,将错误处理留给调用者——如果调用者没有做到这一点,他将得到一个
未处理的PromiserRejection
事件
我能想象的唯一的黑客行为是识别
然后
调用,然后取消自己的错误处理:
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)
正如您所看到的,这只有在函数的调用方完全忽略结果时才有用——这是非常罕见的。如果他这样做了,我建议他还是这样
将使用
处理程序作为onRejected
的默认值:
…
promise.then = function(onFulfilled, onRejected = handler) {
// ^^^^^^^^^
return Promise.prototype.then.call(this, onFulfilled, onRejected);
};
这将激活catchifuncaugh(…)中的默认处理程序代码>大小写,但对于较长链中的调用方来说,这可能是非常不直观的
还请注意,这两种黑客都不能与wait
一起正常工作,它们总是导致调用方需要捕获的异常。对于任何其他需要一个thenable的内置函数也一样——它们总是调用。然后用两个参数调用。不,没有。当您的函数返回一个承诺时,将错误处理留给调用者——如果调用者没有做到这一点,他将得到一个未处理的PromiserRejection
事件
我能想象的唯一的黑客行为是识别然后
调用,然后取消自己的错误处理:
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)
正如您所看到的,这只有在函数的调用方完全忽略结果时才有用——这是非常罕见的。如果他这样做了,我建议他还是这样
将使用处理程序作为onRejected
的默认值:
…
promise.then = function(onFulfilled, onRejected = handler) {
// ^^^^^^^^^
return Promise.prototype.then.call(this, onFulfilled, onRejected);
};
这将激活catchifuncaugh(…)中的默认处理程序代码>大小写,但对于较长链中的调用方来说,这可能是非常不直观的
还请注意,这两种黑客都不能与wait
一起正常工作,它们总是导致调用方需要捕获的异常。对于任何其他需要一个thenable的内置函数也一样——它们总是调用。然后使用两个参数调用。您可以查看这个包
但是您必须更改代码才能使用新机制
导入EPromise
使用YourPromise扩展EPromise扩展它(可选)
将YourPromise.prototype.Uncaught分配给catchIfUncaught
实现
在foo
中更改代码,每个做出承诺的地方都必须更改为使用YourPromise
,等等newyourpromise(executor)/YourPromise.resolve/YourPromise.all/…
你可以看看这个包裹
但是您必须更改代码才能使用新机制
导入EPromise
使用YourPromise扩展EPromise扩展它(可选)
将YourPromise.prototype.Uncaught分配给catchIfUncaught
实现
在foo
中更改代码,每个做出承诺的地方都必须更改为使用YourPromise
,等等newyourpromise(executor)/YourPromise.resolve/YourPromise.all/…
请问您所说的跨环境是什么意思?如果您已经确定了代码无法工作的特定环境,那么明确指出它是什么以及在该环境中出现了什么问题是有意义的,我指的是node.js和浏览器。我知道在这两种环境中都存在全局未处理的拒绝事件,我希望有一个在这两种环境中都有效的解决方案。我更新了示例,以便将fooResult
传递到其他地方。我希望catchIfUncaught处理程序仅在从未捕获到fooResult
的情况下运行。如果捕获块不返回被拒绝的承诺(也不抛出错误),则不会调用后续的捕获块。@sp00m我们如何确定catch
调用的顺序?是否基于执行顺序?另外,你能指出规范中说明这一点的部分吗?你所说的跨环境是什么意思?如果您已经确定了代码无法工作的特定环境,那么明确指出它是什么以及在该环境中出现了什么问题是有意义的,我指的是node.js和浏览器。我知道在这两种环境中都存在全局未处理的拒绝事件,我希望有一个在这两种环境中都有效的解决方案。我更新了示例,以便将fooResult
传递到其他地方。我希望catchIfUncaught处理程序仅在从未捕获到fooResult
的情况下运行。如果捕获块不返回被拒绝的承诺(也不抛出错误),则不会调用后续的捕获块。@sp00m我们如何确定catch
调用的顺序?是否基于执行顺序?另外,你能指出规范中说这是事实的部分吗?我想你可能误解了前提。我不是问catchIfUncaught是否被抓获,而是承诺传递给了catchIfUncaught。假设fooResult被分配给外部作用域中的类或变量的属性。在我的脑海里,catchifuncaugh返回voi