Future(异步操作)

  Future有三种状态未完成完成带有值完成带有异常,使用Future可以简化事件任务。Dart中,可以使用Future对象来表示异步操作的结果,Future返回类型是Future<T>

有三种方法处理Future的结果:

  • then: 处理操作执行结果或者错误并返回一个新的Future
  • catchError: 注册一个处理错误的回调
  • whenComplete:类似final,无论错误还是正确,Future执行结束后总是被调用

使用then来回调,场景使用:UI需要接口的数据,一些异步执行函数

# demo1
main() {Future f1 = new Future(() {print("我是第一个");});f1.then((_) => print("f1 then"));print("我是main");
}
# print:
# 我是main
# 我是第一个
# f3 then

Future和async/await结合使用

使用链式调用的方式把多个future连接在一起,会严重降低代码的可读性。使用async和await关键字实现异步的功能。async和await可以帮助我们像写同步代码一样编写异步代码

Future<String> getStr()async{var str = HttpRequest.getString('www.fgyong.cn');return str;
}

使用http请求地址www.fgyong.cn获取数据,然后返回。如何接收文本呢?

其实很简单,只需要使用await关键字即可,用来注册then回调。

main(List<String> args) async {String string = await getStr();print(string);
}

等同于

main(List<String> args) async {getStr().then((value) {print(value);});
}

stream—连续异步操作

如果Future表示单个计算的结果,则流是一系列结果

侦听流以获取有关结果(数据和错误)以及流关闭的通知。还可以在收听流时暂停播放或在流完成之前停止收听。

可以说Future 用于处理单个异步操作Stream 用来处理连续的异步操作。

Stream 分单订阅流和广播流。

单订阅流在发送完成事件之前只允许设置一个监听器,并且只有在流上设置监听器后才开始产生事件,取消监听器后将停止发送事件。即使取消了第一个监听器,也不允许在单订阅流上设置其他的监听器。广播流则允许设置多个监听器,也可以在取消上一个监听器后再次添加新的监听器。

Stream 有同步流和异步流之分。

它们的区别在于同步流会在执行 addaddError 或 close 方法时立即向流的监听器 StreamSubscription 发送事件,而异步流总是在事件队列中的代码执行完成后在发送事件。

在 Dart 有几种方式创建 Stream

  1. 使用 async* 函数,函数标记为 async *,我们可以使用 yield 作为关键字并返回 Stream 数据
  2. 从现有的生成一个新的流 Stream,使用 mapwheretakeWhile 等方法。
    Stream<int> countStream(int to) async* {for (int i = 1; i <= to; i++) {yield i;}
    }Stream stream = countStream(10);
    stream.listen(print);
  3. 使用 StreamController
    StreamController<Map> _streamController = StreamController(onCancel: () {},onListen: () {},onPause: () {},onResume: () {},sync: false,
    );Stream _stream = _streamController.stream;
  4. 使用 Future 对象生成
    Future<int> _delay(int seconds) async {await Future.delayed(Duration(seconds: seconds));return seconds;
    }List<Future> futures = [];
    for (int i = 0; i < 10; i++) {futures.add(_delay(3));
    }Stream _futuresStream = Stream.fromFutures(futures);

我们在实际的开发过程中,基本都是使用的StreamContoller来创建流。监听使用StreamBuilder,当流发生变化时执行,例子:

import 'dart:async';
import 'package:flutter/material.dart';class StreamCounter extends StatefulWidget {@override_StreamCounterState createState() => _StreamCounterState();
}class _StreamCounterState extends State<StreamCounter> {// 创建一个 StreamControllerStreamController<int> _counterStreamController = StreamController<int>(onCancel: () {print('cancel');},onListen: () {print('listen');},);int _counter = 0;Stream _counterStream;StreamSink _counterSink;// 使用 StreamSink 向 Stream 发送事件,当 _counter 大于 9 时调用 close 方法关闭流。void _incrementCounter() {if (_counter > 9) {_counterSink.close();return;}_counter++;_counterSink.add(_counter);}// 主动关闭流void _closeStream() {_counterStreamController.close();}@overridevoid initState() {super.initState();_counterSink = _counterStreamController.sink;_counterStream = _counterStreamController.stream;}@overridevoid dispose() {super.dispose();_counterSink.close();_counterStreamController.close();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Stream Counter'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('You have pushed the button this many times:'),// 使用 StreamBuilder 显示和更新 UIStreamBuilder<int>(stream: _counterStream,initialData: _counter,builder: (context, snapshot) {if (snapshot.connectionState == ConnectionState.done) {return Text('Done',style: Theme.of(context).textTheme.bodyText2,);}int number = snapshot.data;return Text('$number',style: Theme.of(context).textTheme.bodyText2,);},),],),),floatingActionButton: Row(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[FloatingActionButton(onPressed: _incrementCounter,tooltip: 'Increment',child: Icon(Icons.add),),SizedBox(width: 24.0),FloatingActionButton(onPressed: _closeStream,tooltip: 'Close',child: Icon(Icons.close),),],),);}
}

bloc—状态管理

上文了解到stream,是使用bloc的必要知识。bloc的一个基础使用是CubitCubit类似是bloc的简化版,在一些小的项目上可以使用Cubit。项目维护的数据多使用Bloc最好,下面写的是bloc核心知识和使用案例

bloc处理关系图:

  • Bloc模式

    • bloc:逻辑层
    • state:数据层
    • event:所有的交互事件
    • view:页面

Bloc模板

  • view:默认添加了一个初始化事件
class CounterPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return BlocProvider(create: (BuildContext context) => CounterBloc()..add(InitEvent()),child: Builder(builder: (context) => _buildPage(context)),);}Widget _buildPage(BuildContext context) {final bloc = BlocProvider.of<CounterBloc>(context);return Container();}
}
  • bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {CounterBloc() : super(CounterState().init());@overrideStream<CounterState> mapEventToState(CounterEvent event) async* {if (event is InitEvent) {yield await init();}}Future<CounterState> init() async {return state.clone();}
}
  • event
abstract class CounterEvent {}class InitEvent extends CounterEvent {}
  • state
class CounterState {CounterState init() {return CounterState();}CounterState clone() {return CounterState();}
}

flutter开发核心 Future/stream/bloc相关推荐

  1. Flutter开发——动画原理及核心类

    动画的原理 实际上动画是一段连续的画面,也叫做"动起来的画面",这些画面是由一连串静态的图片组成的,而一个动画画面又叫做"动画帧". 帧又被分为关键帧和过渡帧, ...

  2. 使用Flutter开发Github客户端及学习历程的小结

    本文已授权「玉刚说」微信公众号独家原创发布 本文笔者将尝试分享个人针对Flutter的 学习 并 搭建一个Flutter应用 的过程. 在这一个月学习Flutter的过程中,我不可避免的走了很多弯路, ...

  3. 使用 Flutter 开发 Github 客户端及学习历程的小结

    本文由 却把青梅嗅 授权投稿 原文链接:https://juejin.im/post/5d14f3645188255c117c0fd6 本文笔者将尝试分享个人针对Flutter的 学习 并 搭建一个F ...

  4. 基于Flutter开发的App商城

    计算机工程系 毕业设计报告 题 目: 基于Flutter框架的电子商城制作 专 业: 软件技术 班 级: 17移动互联2班 学 号: 31702160219 学生姓名: 赖康翔 指导教师: 沈大旺 完 ...

  5. Flutter开发指南之理论篇:Dart语法04(库,异步,正则表达式)

    总目录 Flutter开发指南之理论篇:Dart语法01(数据类型,变量,函数) Flutter开发指南之理论篇:Dart语法02(运算符,循环,异常) Flutter开发指南之理论篇:Dart语法0 ...

  6. flutter开发小程序_为什么我认为Flutter是移动应用程序开发的未来

    flutter开发小程序 I dabbled a bit in Android and iOS development quite a few years back using Java and Ob ...

  7. 看!闲鱼又开源了一个 Flutter 开发利器

    阿里妹导读:随着 Flutter 这一框架的快速发展,有越来越多的业务开始使用 Flutter 来重构或新建其产品.但在我们的实践过程中发现,一方面 Flutter 开发效率高,性能优异,跨平台表现好 ...

  8. 重磅开源|AOP for Flutter开发利器——AspectD

    问题背景 随着Flutter这一框架的快速发展,有越来越多的业务开始使用Flutter来重构或新建其产品.但在我们的实践过程中发现,一方面Flutter开发效率高,性能优异,跨平台表现好,另一方面Fl ...

  9. 论Flutter开发如何改善套娃地狱问题

    /   今日科技快讯   / 近日,滴滴旗下自动驾驶公司宣布与广汽埃安新能源汽车有限公司达成战略合作.滴滴出行董事长兼CEO程维与广汽集团董事长曾庆洪,共同见证签约仪式. /   作者简介   / 本 ...

最新文章

  1. 人工智能是什么?带你一次掌握人工智能的三大重点及三大领域
  2. EchoesWorks —— 打造下一代技术Blog/Presentation 框架(招兵买马)
  3. Intellij IDEA中使用Protobuf的正确姿势
  4. 洛谷 1969 积木大赛——水题
  5. post上传代码实现
  6. 第十四章 虚拟专网 ×××
  7. java obix_obix协议在java中的配置和使用详解
  8. oracle导数卡死,oracle-审计导数
  9. linux svn 面板,Linux下SVN服务器搭建(CentOS+Subversion)
  10. sql server伪列_伪简单SQL Server恢复模型
  11. dubbo 自定义路由_高性能可扩展分布式RPC框架Dubbo内核原理揭秘
  12. Adobe Photoshop Pro CC 2019及类似软件注册
  13. SharePoint 通过控制上传下载对文件进行加密解密(二)
  14. 计算机组装大赛活动感悟,计算机组装大赛总结参考
  15. mysql count函数 null_MySql中COUNT(XXX OR NULL)
  16. SpringCloud学习记录 | 第十五篇:SpringCloud Alibaba Nacos配置中心-单机版
  17. ILSVRC2015_VID数据集详解
  18. bridge到blender出现的问题(导入+材质)2.0
  19. TOEFL 备考资料网站
  20. 在ubuntu下用mosquitto搭建mqtt服务器,mqtt.fx的tls加密连接

热门文章

  1. ASPCMS标签教程
  2. MATLAB计算与常用命令
  3. 阿衰小冲用计算机,猫小乐:阿衰错把充电电池当成废旧电池扔进回收箱,惹怒小冲了...
  4. Ubuntu18.04 安装SDN ryu+mininet
  5. Cow Tennis Tournament
  6. netmq VS redis 订阅发布性能研究
  7. 洛谷:P3654 First Step (ファーストステップ)
  8. windows自带Bitlocker使用问题汇总
  9. 室外温度已达34度,本博客提供自助风扇服务
  10. 关于c语言的聊天图片不用打字搞笑,不用打字就可聊天图片大全 不用打字早上好表情包...