Javascript 如何使用JS捕获异步错误?
是否可以使用promises的ES6Javascript 如何使用JS捕获异步错误?,javascript,asynchronous,ecmascript-6,promise,Javascript,Asynchronous,Ecmascript 6,Promise,是否可以使用promises的ES6.catch语法捕获异步错误?例如,以下操作不起作用(.catch未捕获错误): 但此同步版本会: new Promise((resolve, reject)=>{ throw new Error("uh oh"); }).then(number=>{ console.log("Number: " + number); }).catch(e=>{ console.log("Error: " + e); }); 使用t
.catch
语法捕获异步错误?例如,以下操作不起作用(.catch未捕获错误):
但此同步版本会:
new Promise((resolve, reject)=>{
throw new Error("uh oh");
}).then(number=>{
console.log("Number: " + number);
}).catch(e=>{
console.log("Error: " + e);
});
使用try/catch块和reject
清除catch中的错误是执行以下操作的唯一解决方案吗
new Promise((resolve, reject)=>{
try {
setTimeout(()=>{throw new Error("uh oh")}, 1);
}
catch(e) {
reject(e);
}
}).then(number=>{
console.log("Number: " + number);
}).catch(e=>{
console.log("Error: " + e);
});
对于这个问题,假设抛出错误的代码部分位于另一个命名函数中,因此它没有访问reject
函数的权限
谢谢
编辑:在Promise
构造函数中使用resolve()
,reject()
。在onRejected
或.catch()
处处理错误
注意,一旦处理了错误,应到达chained处的oncompleted
。然后(
),如果有,除非throw
在onRejected
或.catch()
中使用throw
,以明确地将错误传递给chained。然后(\uu,onRejected)
或.catch()
函数fn(){
抛出新错误(“啊哦”)
}
新承诺((解决、拒绝)=>{
设置超时(()=>{
试一试{
解析(fn())
}捕获(e){
拒绝(e)
}
}, 1);
})。然后(数字=>{
控制台日志(“编号:+编号);
},e=>{
控制台日志(“错误:+e”);
});代码>
“为了解决这个问题,假设抛出错误的代码部分位于另一个命名函数中,因此它无法访问拒绝函数。”–Christopher Shroba
“这个(代码中不存在的)函数是否返回承诺?”–Jaromanda X
“是的,另一个函数通常会返回一个承诺,,但由于该函数中的异步函数正在抛出一个错误,因此整个函数正在抛出一个错误。”–Christopher Shroba
好吧,下次发布你的代码,因为你用英语描述问题的能力永远不会像实际代码那么好。“异步函数”是指返回承诺的函数吗?如果是的话
不管你的承诺中有多大的错误。下面是一个示例函数three
,它调用一个函数two
,该函数调用一个函数one
,如果JSON格式不正确,则可能引发错误。每一步都对最终的计算做出了有价值的贡献,但是如果one
抛出一个错误,它将在整个承诺链中冒泡
constone=(json)=>newpromise((解析,拒绝)=>{
解析(JSON.parse(JSON))
})
consttwo=(json)=>one(json)。然后(data=>data.hello)
constthree=(json)=>two(json)。然后(hello=>hello.toUpperCase())
三个({“hello”:“world”})。然后(console.log,console.error)
//“世界”
三个('bad json')。然后(console.log、console.error)
//错误:JSON中位于位置0处的意外标记b
无法像第一个示例那样捕获抛出的错误。这里的问题是,您正在使用显式承诺构造反模式。您正试图让Promise
构造函数完成超出其需要的工作
相反,您应该承诺最少的异步功能,并在此基础上构建。在本例中,这将涉及生成一个承诺,在解析之前等待一定时间。大多数第三方promise库已经有了.delay()
方法,但创建自己的方法非常容易:
let delay = duration => new Promise(resolve => setTimeout(resolve, duration));
然后,您可以在此基础上构建,并轻松捕获错误:
letdelay=duration=>newpromise(解析=>setTimeout(解析,持续时间));
延迟(1)
.然后(()=>{
抛出新的错误(“啊哦”);
})
。然后(数字=>{
控制台日志(“编号:+编号);
}).catch(e=>{
控制台日志(“错误:+e”);
});
假设抛出错误的代码部分在另一个命名函数中
-此(代码中不存在)函数是否返回承诺?是的,另一个函数正常返回承诺,但由于该函数中的异步函数抛出错误,整个函数抛出错误。我知道第一个代码片段不能仅仅通过运行它来工作;期望的行为是“Error:”应该是console.log'ed,但实际上错误是从链式调用中传播出来的:否,catch
不会捕获超时内抛出的错误,因为它位于不同的“线程”中。我想我应该放弃抛出错误的欲望,而拒绝它…?这可能是一个有用的读物:我可以建议在承诺链的末尾使用。catch
,而不是使用的第二个参数吗?这样,它将捕获承诺链中的任何错误.catch(e=>{console.log(“Error:+e);})
不确定您的意思?错误在onRejected
at处处理。然后(oncompleted,onRejected)
,如果throw
在onRejected
处没有使用chained。然后()
到达oncompleted
。我的意思是:如果不认为这样更好,请告诉我。我不明白你为什么不这么做。例如,如果OP的真实世界用例中的承诺链很长,我想这会更安全。@RaphaelRafatpanah“更好”是什么意思<代码>javascript
在jsfiddle链接和在jsfiddle链接是相同的模式,是吗?OP可以在被拒绝时抛出错误或.catch()
,或不在链接的位置抛出错误。然后()
如果有,应该在可能的链接处到达已完成时
。然后()
。错误在onRejected
或.catch()
处处理。这取决于是否抛出处理过的错误的预期结果
let delay = duration => new Promise(resolve => setTimeout(resolve, duration));