Javascript 承诺拒绝会抛出警告,即使它';It’以后会被抓到的
示例Javascript 承诺拒绝会抛出警告,即使它';It’以后会被抓到的,javascript,node.js,typescript,promise,Javascript,Node.js,Typescript,Promise,示例 class Foo { private pro = new Promise(() => { throw new Error(); }); public usePro() { return this.pro.then(() => {}); } } let foo = new Foo(); setTimeout(() => { foo.usePr
class Foo {
private pro = new Promise(() => {
throw new Error();
});
public usePro() {
return this.pro.then(() => {});
}
}
let foo = new Foo();
setTimeout(() => {
foo.usePro().then(() => {
console.log("end.");
}).catch(() => {
console.log("error.");
})
}, 1000);
(node:39166) UnhandledPromiseRejectionWarning: error
(node:39166) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:39166) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
error.
(node:39166) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
我知道javascript在运行时无法知道稍后会有人捕获错误,那么在这种情况下我该怎么做呢
控制台
class Foo {
private pro = new Promise(() => {
throw new Error();
});
public usePro() {
return this.pro.then(() => {});
}
}
let foo = new Foo();
setTimeout(() => {
foo.usePro().then(() => {
console.log("end.");
}).catch(() => {
console.log("error.");
})
}, 1000);
(node:39166) UnhandledPromiseRejectionWarning: error
(node:39166) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:39166) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
error.
(node:39166) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
无论在哪里使用承诺,都应该捕获错误,即使该承诺稍后被其他东西返回(并捕获)。一个选项是分配给
this.proValue
一个已解决的
对象或一个已拒绝的
对象,具体取决于原始承诺是已解决还是拒绝。然后,当调用usePro
时,检查this.proValue
并返回Promise.resolve(已解决)
或Promise.reject(已拒绝)
。使用标准Javascript以便可以在可运行的代码段中显示:
class-Foo{
构造函数(){
this.pro=新承诺(()=>{
抛出新错误('Problem!');
})
。然后((已解决)=>{
this.proValue={resolved};
})
.catch((拒绝)=>{
this.proValue={拒绝};
});
}
usePro(){
const{resolved,rejected}=this.proValue;
如果(已解决)返回承诺。解决(已解决);
否则,如果(拒绝)返回承诺。拒绝(拒绝);
}
}
const foo=新foo();
设置超时(()=>{
foo.usePro()。然后(()=>{
控制台日志(“结束”);
}).catch((e)=>{
console.log(“捕获错误”。+e);
})
}, 1000);代码>回答得很好
让我将其添加到Node.js
中,您还可以在进程上添加一个未处理的Rejection
侦听器:
process.on('unhandledRejection', reason => {
console.error({Error:reason})
process.exit(1);
});
您可以使用Promise.all延迟解决:
const delay = ms => new Promise(res => setTimeout(res, ms));
Promise.all([
foo.usePro(),
delay(1000)
]).then(() => {
console.log("end.");
}).catch(() => {
console.log("error.");
});
这样就可以直接连接.catch
,但在延迟之后执行then回调。如果在承诺解决之前调用usePro()
,则这将不起作用。没错,请参阅编辑。有点难看,我想不出一种方法可以在每次调用usePro
时手动构建一个新的承诺,这太复杂了。为什么不将proValue
存储在一个承诺本身中——一个永远不会被拒绝的承诺?你基本上是在重新发明。你不认为忽略所有可能来自其他地方的警告是危险的吗?我不是说忽略所有警告,而是要倾听可能来自未知来源的未处理的弹出。一旦你抓住了它们,当然你应该开始重构你的代码。我只是添加了上面的答案,作为错误处理的良好实践,特别是在开发过程中。您如何确保稍后有人会发现错误?也,