使用bluebird promise进行异步异常处理
Asynchronous exception handling with bluebird promises
处理这种情况的最佳方法是什么。我在一个可控的环境中,我不想撞车。
var Promise = require('bluebird');
function getPromise(){
return new Promise(function(done, reject){
setTimeout(function(){
throw new Error("AJAJAJA");
}, 500);
});
}
var p = getPromise();
p.then(function(){
console.log("Yay");
}).error(function(e){
console.log("Rejected",e);
}).catch(Error, function(e){
console.log("Error",e);
}).catch(function(e){
console.log("Unknown", e);
});
当从setTimeout内抛出时,我们总是会得到:
$ node bluebird.js
c:'blp'rplus'bbcode'scratchboard'bluebird.js:6
throw new Error("AJAJAJA");
^
Error: AJAJAJA
at null._onTimeout (c:'blp'rplus'bbcode'scratchboard'bluebird.js:6:23)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
如果投掷发生在setTimeout之前,那么蓝鸟接球会接住它:
var Promise = require('bluebird');
function getPromise(){
return new Promise(function(done, reject){
throw new Error("Oh no!");
setTimeout(function(){
console.log("hihihihi")
}, 500);
});
}
var p = getPromise();
p.then(function(){
console.log("Yay");
}).error(function(e){
console.log("Rejected",e);
}).catch(Error, function(e){
console.log("Error",e);
}).catch(function(e){
console.log("Unknown", e);
});
结果:
$ node bluebird.js
Error [Error: Oh no!]
这很好,但如何处理节点或浏览器中这种性质的恶意异步回调。
然而,Promise确实捕获了从then
/catch
/Promise
构造函数回调中抛出的异常。所以使用
function getPromise(){
return new Promise(function(done, reject){
setTimeout(done, 500);
}).then(function() {
console.log("hihihihi");
throw new Error("Oh no!");
});
}
(或仅Promise.delay
(以获得期望的行为。永远不要抛出自定义(非promise(异步回调,永远拒绝周围的promise。如果确实需要,请使用try-catch
。
在处理了您所描述的相同场景和需求后,我发现了zone.js,这是一个在多个框架中使用的令人惊叹的javascript库(Angular就是其中之一(,它使我们能够以非常优雅的方式处理这些场景。
Zone是一个在异步任务中持续存在的执行上下文。您可以将其视为JavaScript虚拟机的线程本地存储
使用示例代码:
import 'zone.js'
function getPromise(){
return new Promise(function(done, reject){
setTimeout(function(){
throw new Error("AJAJAJA");
}, 500);
});
}
Zone.current
.fork({
name: 'your-zone-name',
onHandleError: function(parent, current, target, error) {
// handle the error
console.log(error.message) // --> 'AJAJAJA'
// and return false to prevent it to be re-thrown
return false
}
})
.runGuarded(async () => {
await getPromise()
})
感谢@Bergi。现在我知道promise不会在异步回调中捕获错误。以下是我测试过的3个例子。
注意:拒绝调用后,函数将继续运行。
示例1:拒绝,然后在promise构造函数回调中抛出错误
示例2:拒绝,然后在setTimeout异步回调中抛出错误
示例3:拒绝,然后在setTimeout异步回调中返回以避免崩溃
// Caught
// only error 1 is sent
// error 2 is reached but not send reject again
new Promise((resolve, reject) => {
reject("error 1"); // Send reject
console.log("Continue"); // Print
throw new Error("error 2"); // Nothing happen
})
.then(() => {})
.catch(err => {
console.log("Error", err);
});
// Uncaught
// error due to throw new Error() in setTimeout async callback
// solution: return after reject
new Promise((resolve, reject) => {
setTimeout(() => {
reject("error 1"); // Send reject
console.log("Continue"); // Print
throw new Error("error 2"); // Did run and cause Uncaught error
}, 0);
})
.then(data => {})
.catch(err => {
console.log("Error", err);
});
// Caught
// Only error 1 is sent
// error 2 cannot be reached but can cause potential uncaught error if err = null
new Promise((resolve, reject) => {
setTimeout(() => {
const err = "error 1";
if (err) {
reject(err); // Send reject
console.log("Continue"); // Did print
return;
}
throw new Error("error 2"); // Potential Uncaught error if err = null
}, 0);
})
.then(data => {})
.catch(err => {
console.log("Error", err);
});
相关文章:
- node.js和express中的异常处理
- JavaScript 异常处理未按预期工作
- tomcat服务器停止时UI上的异常处理
- 带异常处理的基数转换
- 从CORS请求中捕获异步异常
- Javascript getJson异常处理
- 在正确的上下文中捕获异步异常
- 使用生成器进行异常处理
- 如何在保留 JavaScript 调试器功能的同时进行优雅的异常处理
- 了解 JavaScript 中的异常处理:当更改 try/catch 块的位置时,获得不同的输出
- 流星中的异常处理
- 角.如何在视图中显示异常处理程序的错误
- $.each 中的异步错误处理
- 如何将节点 js 的异步功能处理为在节点 js 中同步
- 异步如何处理 Javascript 中的变量
- 如何使工作 Chrome 扩展程序的未捕获异常处理程序(由于 CORS 保护而不起作用)
- Javascript异步循环处理
- 使用bluebird promise进行异步异常处理
- Node.js最佳实践异常处理-异步/Await之后
- 使用node.js的异步异常处理