# 异常处理
# 心法口诀
同步的异常同步做,
异步的异常异步做,
未处理的异常runZoned做,
# 同步异常
与其它语言一样,dart提供类try/catch来来接异常信息,防止未处理的异常而导致后面的代码无法正常运行。
代码语言:javascript复制try {
throw 'sync error';
} catch (e) {
print(e);
}
# 异步异常
异步异常指Future中的异常,Future是一个事件循环循环对象,该对象的异常是通过catchError
回调来拦截的,如果要使用try/catce的方式拦击,需要将Future变成一个同步对象,变成同步对象很简单,只要await Future
就可以了。
//获取Future异常
Future(() {
throw 'error';
}).catchError((e){
print(e);
});
//也可以通过try/catch获取异常
try {
await Future(() {
throw 'error';
});
} catch (e) {
print(e);
}
### 全局异常runZoned
runZoned直译过来是运行区域的意思,它有什么用呢?这里我们可以将它作为代码区域异常全局处理程序,当然除了全局异常处理之外还有其它的功能。
使用runZoned很简单,它的接收一个匿名函数,也就是它包裹了这个匿名的函数的执行范围,另外通过onError参数我们可以指定一个错误处理函数,当匿名函数内存在未处理的异常时,该错误处理函数就会拦截这个异常。
代码语言:javascript复制// 全局函数异常
runZoned(() {
throw 'error';
}, onError: (e) {
print('global handler error');
});
// 匿名函数自己处理异常
runZoned(() {
try {
throw 'error';
} catch (e) {
print("self handler error");
}
}, onError: (e) {
print('global handler error');
});
下面一个Future的例子,加深你对Future的理解
代码语言:javascript复制runZoned(() async{
try {
Future.error('error');
} catch (e) {
print("self handler error");
}
}, onError: (e) {
print('global handler error');
});
// 执行结果:global handler error
runZoned(() async{
try {
//同步时需要放在try/catch中执行
await Future.error('error');
} catch (e) {
print("self handler error");
}
}, onError: (e) {
print('global handler error');
});
// 执行结果:self handler error
下面看一个Stream的例子
代码语言:javascript复制runZoned(() async {
Stream.error('error').listen((data) {
print(data);
}, onError: (e) {
print('self handler error');
});
}, onError: (e) {
print('global handler error');
});
//await for的方式监听stream时会导致异常
//这是因为stream每次返回一个Future对象,
//实际await等待的是data即:await data,for只是遍历Stream对象
runZoned(() async {
await for (var data in Stream.error('error')) {}
}, onError: (e) {
print('global handler error');
});
runZoned(() async {
try {
await for (var data in Stream.error('error')) {}
} catch (e) {
print('self handler error');
}
}, onError: (e) {
print('global handler error');
});