Flutter异步:Future与FutureBuilder实用技巧

什么是Future

表示在接下来的某个时间的值或错误,借助Future我们可以再Flutter实现异步操作。

它类似于ES6中的Promise,提供then和catchError的链式调用

Future是dart:async包中的一个类,使用它的时候需要导入dart:async包,Future有两种状态:

  • pending : 执行中
  • completed : - 执行结束,分两种情况要么成功要么失败

Future的常见用法

使用future.then获取future的值与捕获future的异常
Future<String> testFuture() {
  //throw new Error();
  return Future.value("success");
  //return Future.error("error");
}

void main() {
  testFuture().then((s) {
	print(s);
	}, onError: (e) {
    print("onError:");
    print(e);
  }).catchError((e) {
    print("catchError:");
    print(e);
  });
}

如果catchError与onError同时存在,则只会调用onError

结合async await

Future是异步的,如果我们要将异步转同步,那么可以借助async await 来完成

import 'dart:async';

test() async {
  int result = await Future.delayed(Duration(milliseconds: 2000),(){
    return Future.value(123);
  });
  print("t3:"+DateTime.now().toString());
  print(result);
}

void main() {
  print("t1:"+DateTime.now().toString());
  test();
  print("t2:"+DateTime.now().toString());
}

运行结果

I/flutter (20667): t1:2019-06-14 15:58:04.892591
I/flutter (20667): t2:2019-06-14 15:58:04.941420
I/flutter (20667): t3:2019-06-14 15:58:06.951207
future.whenComplete

有时候我们需要在Future结束的时候做些事情,我们知道then().catchError()的模式类似于try-catch,try-catch有个finally代码块,而future.whenComplete就是Future的finally。

Future.value("success")
.then((s) {
    print(s);
  }).catchError((e) {
    print("catchError:");
    print(e);
  }).whenComplete((){
    print("complete")
  });
future.timeout

完成一个异步操作可能需要很长的时间,比如网络请求,但有时我们需要为异步操作设置一个超时时间。

new Future.delayed(new Duration(seconds: 3), () {})
  .timeout(new Duration(seconds: 2))
  .then((s) {
print("then");
  }).catchError(() {
    print("catchError");
  });

运行后可以看到日志

E/flutter (20667): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: TimeoutException after 0:00:02.000000: Future not completed

什么是FutureBuilder

FutureBuilder是一个将异步操作和异步UI更新结合在一起的类,通过它我们可以将网络请求,数据库读取等结果更新到页面上。

FutureBuilder常见的用法

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String showResult = '';
  Future<CommonModel> fetchPost() async {
    final response = await http.get('http://www.devio.org/io/flutter_app/json/test_common_model.json');
    Utf8Decoder utf8decoder = Utf8Decoder(); //fix 中文乱码
    var result = json.decode(utf8decoder.convert(response.bodyBytes));
    return CommonModel.fromJson(result);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Future与FutureBuilder实用技巧'),
        ),

        body: FutureBuilder<CommonModel>(
            future: fetchPost(),
            builder:
                (BuildContext context, AsyncSnapshot<CommonModel> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return new Text('Input a URL to start');
                case ConnectionState.waiting:
                  return new Center(child: new CircularProgressIndicator());
                case ConnectionState.active:
                  return new Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return new Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return new Column(children: <Widget>[
                      Text('icon:${snapshot.data.icon}'),
                      Text('statusBarColor:${snapshot.data.statusBarColor}'),
                      Text('title:${snapshot.data.title}'),
                      Text('url:${snapshot.data.url}')
                    ]);
                  }
              }
            }),
      ),
    );
  }
}

class CommonModel {
  final String icon;
  final String title;
  final String url;
  final String statusBarColor;
  final bool hideAppBar;
  CommonModel(
      {this.icon, this.title, this.url, this.statusBarColor, this.hideAppBar});
  factory CommonModel.fromJson(Map<String, dynamic> json) {
    return CommonModel(
      icon: json['icon'],
      title: json['title'],
      url: json['url'],
      statusBarColor: json['statusBarColor'],
      hideAppBar: json['hideAppBar'],
    );
  }
}
其他

详见https://www.jianshu.com/p/78fe79648596

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值