Javascript 如何使用JS捕获异步错误?

Javascript 如何使用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

是否可以使用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);
});
使用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));