![](/img/trans.png)
[英]How do I catch an asynchronous error from a function without promises?
[英]How can I catch an asynchronous error using JS promises?
是否可以使用promises的ES6 .catch
语法捕获异步错误? 例如,以下不起作用(.catch不捕获错误):
new Promise((resolve, reject)=>{
setTimeout(()=>{throw new Error("uh oh")}, 1);
}).then(number=>{
console.log("Number: " + number);
}).catch(e=>{
console.log("Error: " + e);
});
但是这个同步版本可以:
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()
处理错误。
注意,一旦处理了错误,就onFulfilled
在链接onFulfilled
.then()
onFulfilled
,如果有的话,除非在onRejected
或.catch()
使用throw
,以显式地将错误传递给链接.then(_, onRejected)
或.catch()
function fn() { throw new Error("uh oh") } new Promise((resolve, reject) => { setTimeout(() => { try { resolve(fn()) } catch (e) { reject(e) } }, 1); }).then(number => { console.log("Number: " + number); }, e => { console.log("Error: " + e); });
没有办法像第一个例子那样捕获错误。 这里的问题是您使用的是Explicit Promise Construction Antipattern。 您正在尝试让Promise
构造函数执行更多操作。
相反,您应该宣传最少量的异步功能,并在此基础上构建。 在这种情况下,这将涉及产生在解决之前等待一定时间的承诺。 大多数第三方承诺库已经有了.delay()
方法,但创建自己的方法非常简单:
let delay = duration => new Promise(resolve => setTimeout(resolve, duration));
然后你可以在此基础上构建,并轻松捕获错误:
let delay = duration => new Promise(resolve => setTimeout(resolve, duration)); delay(1) .then(() => { throw new Error("uh oh"); }) .then(number => { console.log("Number: " + number); }).catch(e => { console.log("Error: " + e); });
“为了这个问题,假设抛出错误的代码部分在另一个命名函数中,因此它无法访问拒绝函数。” - 克里斯托弗Shroba
“这个(你的代码中不存在)函数会返回一个Promise吗?” - Jaromanda X.
“是的,另一个函数通常会返回一个promise, 但由于该函数内部的异步函数抛出了一个Error ,整个函数都会抛出一个Error。” - 克里斯托弗Shroba
那么下次发布您的代码时,因为您用英语描述问题的能力永远不会像实际代码那样好。 “异步函数”是指一个返回promise的函数吗? 如果是这样的话 ...
错误在你的Promises中的深度并不重要。 下面是一个例子功能three
它调用的函数two
它调用一个函数one
具有潜力抛出一个错误的JSON形式不佳的情况下。 每一步都使最终计算的宝贵贡献,但在事件one
抛出一个错误,它会冒泡通过承诺的整个链条。
const one = (json) => new Promise((resolve, reject) => { resolve(JSON.parse(json)) }) const two = (json) => one(json).then(data => data.hello) const three = (json) => two(json).then(hello => hello.toUpperCase()) three('{"hello":"world"}').then(console.log, console.error) // "WORLD" three('bad json').then(console.log, console.error) // Error: unexpected token b in JSON at position 0
否则通过“异步函数”你的意思是它是一个不返回Promise并且可能使用延续的函数? 在这种情况下,我们将修改one
以在承诺中包装异步函数,然后two
和three
将工作相同。 重要的是,我没有使用try
/ catch
在我的任何承诺的功能
// continuation passing style async function const asyncParse = (json, k) => { try { k(null, JSON.parse(json)) } catch (err) { k(err) } } // one now wraps asyncParse in a promise const one = (json) => new Promise((resolve, reject) => { asyncParse(json, (err, data) => { if (err) reject(err) else resolve(data) }) }) // everything below stays the same const two = (json) => one(json).then(data => data.hello) const three = (json) => two(json).then(hello => hello.toUpperCase()) three('{"hello":"world"}').then(console.log, console.error) // "WORLD" three('bad json').then(console.log, console.error) // Error: unexpected token b in JSON at position 0
哦,如果你有一个函数f
,它不能以这两种方式中的任何一种运行 - 即抛出错误但不返回承诺或将错误发送到延续的函数 - 你正在处理一块垃圾和你写的代码取决于f
也将是垃圾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.