【flutter学习笔记】Future

404 阅读2分钟

Future用来表示将来可能会出现的值或者错误。可以注册回调来处理其返回的值或者错误。例如

    Future<int> future = getFuture();
    future.then((value) => handleValue(value))
          .catchError((error) => handleError(error));

某些时候可以用一个future去接受另外一个future的value或者error 。

Future<int> successor = future.then((int value){
    return 42;
}, onError: (e){
   if(canHandle(e)){
       return 499;
   } else {
       throw e;
   }
});

需要注意的是当一个Future在拥有接收者之前报错的话,则接收者的catchError将捕获不到异常,会被全局的error-handler捕获,目的是防止异常被静默删除。这就意味着错误处理应该提前注册,以便及时处理错误。以下实例就潜在上述问题:

var future = getFuture();
new Timer(Duration(millisecords: 5),(){
    //显然如果在5millisecords内报错之后的onError将捕获不到此异常
    future.then((value){userValue(vale)},
    onError:(e){handleError(e)});
});

通常我们需要给Future注册两个回调来增加其可读性。

Future future = Future(foo);
future.then((value) => handleValue(value)).catchError((e) => handleError(e));

//当然还有这种
Future future = Future(foo);
future.then((value) => handleValue(value),onError(e) => handleError(e));

上述两种写法第一种会catch foo方法的异常以及 handleValue(value)方法的异常。第二种则只关注foo的异常。

特殊场景的try catch

Future<void> foo() async{
    throw Exception('1');
}

Future<void> foo1(){
     throw Exception('2');
}

Future<void> foo2(){
     throw Exception('3');
}

void main() async{
    foo().catchError((e) => handleError(e));
    foo1().catchError((e) => handleError(e));
    try {
      await foo2();
    } catch (e) {
      print(e);
    }
}

运行之后或发现foo1()方法中的exception2 是没有被catch住的,这时我们再看catchError的注释 Handles errors emitted by this [Future],翻译过来就是处理由这个Future提交的exception,在不加async的时throw将不会被认定为Future提交的错误,而是一个同步错误。需要像foo2一样使用同步try catch 方式去捕获。为了使得代码可读性提高,如果需要在Future 抛出异常的话,我们应该使用如下的方式:

Future<void> foo3(){
 reture Future.error(Exception('4')) ;
}