Flutter之异步编程(下)

Flutter之异步编程(下)
Stream

Stream是Dart语言中所谓异步数列的东西,直白点就是一个异步数据队列。为了控制Stream我们通常采用StreamController来进行管理,sink作为入口函数,StreamController提供stream属性作为数据的出口,StreamController.stream.listen用来监听Stream是否有数据

一、Stream分类
  • 单订阅流
  • 多订阅流
二、Stream 创建
  Flutter 提供了多种创建 Stream 的方式;

1.Stream.periodic

//stream_create_periodic.dart文件
import 'dart:async';

void main(){
  //创建Stream
  createStream();
}

createStream() async{
  //使用periodic创建流,第一个参数为间隔时间,第二个参数为回调函数
  Stream<int> stream = Stream<int>.periodic(Duration(seconds: 1), callBack);
  //await for循环从流中读取
  await for(var i in stream){
    print(i);
  }
}

//可以在回调函数中对值进行处理,这里直接返回了
int callBack(int value){
  return value;
}

2.Stream.fromFutrue

//stream_create_from_future.dart文件
import 'dart:async';

void main(){
  //创建一个Stream
  createStream();
}

createStream() async{
  print("开始测试");
  //创建一个Future对象
  Future<String> future = Future((){
    return "异步任务";
  });

  //从Future创建Stream
  Stream<String> stream = Stream<String>.fromFuture(future);
  //await for循环从流中读取
  await for(var s in stream){
    print(s);
  }
  print("结束测试");
}

3.Stream.fromFutrues

//stream_create_from_futures.dart文件
import  'dart:io';

void main(){
  //从多个Future创建Stream
  createStreamFromFutures();
}

createStreamFromFutures() async{
  print("开始测试");

  Future<String> future1 = Future((){
    //模拟耗时5秒
    sleep(Duration(seconds:5));
    return "异步任务1";
  });

  Future<String> future2 = Future((){
    return "异步任务2";
  });

  Future<String> future3 = Future((){
    return "异步任务3";
  });

  //将多个Future放入一个列表中,将该列表传入
  Stream<String> stream = Stream<String>.fromFutures([future1,future2,future3]);
  //读取Stream
  await for(var s in stream){
    print(s);
  }
  
  print("结束测试");
}

4.Stream.fromIterable

//stream_create_from_iterable.dart文件
import 'dart:async';

void main(){
  //从一个集合创建Stream
  createStream();
}

createStream() async{
  print("开始测试");
  //从集合创建Stream
  Stream<int> stream = Stream<int>.fromIterable([1,2,3,4,5,6]);
  //读取Stream
  await for(var s in stream){
    print(s);
  }
  print("结束测试");
}
  1. Stream 操作方法
    1.stream.take
//stream_take.dart文件
import 'dart:async';

void main(){
  //创建Stream
  createStream();
}

void createStream() async{
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //指定发送事件个数
  stream = stream.take(10);
  //输出Stream
  await for(int i in stream ){
    print(i);
  }
}

2.stream.takeWhile

//stream_take_while.dart文件
import 'dart:async';

void main(){
  //创建Stream
  createStream();
}

void createStream() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //根据返回结果做返回值的限制
  stream = stream.takeWhile((data) {
    //返回值的限制条件
    return data < 8;
  });
  //输出Stream
  await for (int i in stream) {
    print(i);
  }
}

3.stream.skio(int count)

//stream_skip.dart文件
import 'dart:async';

void main(){
  //创建Stream,跳过指定个数元素
  testSkip();
}

void testSkip() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //指定发送事件次数
  stream = stream.take(10);
  //跳过前两个元素
  stream = stream.skip(2);
  //输出Stream
  await for (int i in stream) {
    print(i);
  }
}

4.stream.skioWhile

//stream_skip_while.dart文件
import 'dart:async';

void main(){
  //创建Stream,按条件跳过元素
  testSkipWhile();
}

void testSkipWhile() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //指定发送事件个数
  stream = stream.take(10);
  //根据条件跳过元素,条件为返回值小于5
  stream = stream.skipWhile((data) => data<5);
  //输出Stream
  await for (int i in stream) {
    print(i);
  }
}

5.stream.toList()

//stream_to_list.dart文件
import 'dart:async';

void main(){
  //创建Stream,将流中的数据放在List里
  testToList();
}

void testToList() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //指定发送事件个数
  stream = stream.take(10);
  //将流中所有的数据收集存放在List中
  List<int> listData = await stream.toList();
  //输出List数据
  for(int i in listData){
    print(i);
  }
}

5.stream.listen()

//stream_listen.dart文件
import 'dart:async';

void main(){
  //创建Stream,使用list方法监听流
  testListen();
}

void testListen() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  stream = stream.take(10);
  //监听流
  stream.listen((data){
    print(data);
  },onError:(error){
    print("流发生错误");
  },onDone:(){
    print("流已完成");
  }, cancelOnError: false);
}

6.stream.forEach()

//stream_for_each.dart文件
import 'dart:async';

void main(){
  //创建Stream,使用Stream的forEach迭代输出数据
  testForEach();
}

void testForEach() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  stream = stream.take(5);
  //Stream迭代输出数据
  stream.forEach((data) {
    print(data);
  });
}

7.stream.length

//stream_length.dart文件
import 'dart:async';

void main(){
  //创建Stream,并统计事件的总数量
  testStreamLength();
}

void testStreamLength() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  stream = stream.take(5);
  //统计事件的总数量
  var allEvents = await stream.length;
  print(allEvents);
}

8.stream.length

//stream_length.dart文件
import 'dart:async';

void main(){
  //创建Stream,并统计事件的总数量
  testStreamLength();
}

void testStreamLength() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  stream = stream.take(5);
  //统计事件的总数量
  var allEvents = await stream.length;
  print(allEvents);
}

8.stream.where

//stream_where.dart文件
import 'dart:async';

void main(){
  //创建Stream,并按指定条件筛选出数据
  testWhere();
}

void testWhere() async {
  //时间间隔为1秒
  Duration interval = Duration(seconds: 1);
  //每隔1秒发送1次的事件流
  Stream<int> stream = Stream.periodic(interval, (data) => data);
  //筛选条件为返回值大于2的所有数据
  stream = stream.where((data)=>data>2);
  //筛选条件为返回值小于6的所有数据
  stream = stream.where((data)=> data<6);
  //最后取上面两件条件都满足的数据
  await for(int i in stream){
    print(i);
  }
}
三、StreamController使用

上面直接创建流的方式在实际开发中用途不是很大,基本都是用StreamController来创建流

构建单订阅流

//stream_single.dart文件
import 'dart:async';

void main(){
  //StreamController里面会创建一个Stream,我们实际操控的Stream
  StreamController<String> streamController = StreamController();
  //监听流数据
  streamController.stream.listen((data)=> print(data));
  //添加数据
  streamController.sink.add("aaa");
  //添加数据
  streamController.add("bbb");
  //添加数据
  streamController.add("ccc");
  //关闭流
  streamController.close();
}

构建多订阅流

  • 直接创建多订阅流
//stream_broadcast.dart文件
import 'dart:async';

void main(){
  //使用StreamController的broadcast方法可以直接创建多订阅流
  StreamController<String> streamController = StreamController.broadcast();
  //第一个监听
  streamController.stream.listen((data){
    print('第一次的监听数据:'+ data);
  },onError: (error){
    print(error.toString());
  });
  //第一个监听
  streamController.stream.listen((data){
      print('第二次的监听数据:'+ data);
  });
  //添加数据
  streamController.add("Dart...");
}

将单订阅流转化为多订阅流

//stream_as_broadcast.dart文件
import 'dart:async';

void main(){
  //实例化StreamController对象
  StreamController<String> streamController = StreamController();
  //将单订阅流转换成多订阅流
  Stream stream =streamController.stream.asBroadcastStream();
  //添加第一次监听
  stream.listen((data){
    print('第一次的监听数据:'+ data);
  });
  //添加第二次监听
  stream.listen((data){
    print('第二次的监听数据:'+ data);
  });
  streamController.sink.add("Dart...");
  //关闭流
  streamController.close();
}
四、StreamBuilder

Futter里面提供了一个Widget名叫StreamBuilder其实是一直记录这流中最新的数据,当数据流发生变化时,会自动调用build方法重新渲染组件

//stream_stream_builder.dart文件
import 'dart:async';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'StreamBuilder示例',
      home: MyHomePage(),
    );
  }
}

//有状态组件
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  //计数器值
  int _count = 0;
  //实例化一个StreamController对象
  final StreamController<int> _streamController = StreamController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('StreamBuilder示例'),
      ),
      body: Container(
        child: Center(
          //StreamBuilder组件,数据类型为int
          child: StreamBuilder<int>(
              //指定stream属性
              stream: _streamController.stream,
              //构建器,可以通过AsyncSnapshot拿到流中的数据
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                //这里不需要_count值,从流中取出data即可
                return snapshot.data == null
                    ? Text("0",style: TextStyle(fontSize: 36.0))
                    : Text("${snapshot.data}", style: TextStyle(fontSize: 36.0),
                );
              }),
        ),
      ),
      //操作按钮
      floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.add),
          onPressed: (){
            //向Stream里添加数据
            _streamController.sink.add(++_count);
          }),
    );
  }

  @override
  void dispose() {
    //当界面销毁时关闭Stream流
    _streamController.close();
    super.dispose();
  }
}

响应式编程,Bloc解耦

//stream_bloc_base.dart文件
//定义Bloc抽象类
abstract class BlocBase {
  //定义销毁方法,子类必需实现此方法
  void dispose();
}
//stream_bloc_counter.dart文件
import 'dart:async';
import 'bloc_base.dart';

//继承BlocBase
class BlocCounter extends BlocBase {

  //初例化StreamController,数据类型为int
  final _controller = StreamController<int>();

  //获取到StreamController的sink,即入口可以添加数据
  get _counter => _controller.sink;

  //获取到StreamController的stream,即出口可以取数据
  get counter => _controller.stream;

  //增加计算器值
  void increment(int count) {
    //向流中添加数据
    _counter.add(++count);
  }

  //销毁
  void dispose() {
    //关闭流
    _controller.close();
  }
}
//stream_bloc_main.dart文件
import 'package:flutter/material.dart';

import 'blocs/bloc_counter.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Bloc示例',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState(BlocCounter());
}

class _MyHomePageState extends State<MyHomePage> {

  //组件计数变量
  int _counter = 0;

  //计数器Bloc
  final BlocCounter bloc;

  _MyHomePageState(this.bloc);

  //计数增加方法
  void _incrementCounter() {
    //调用bloc的方法
    bloc.increment(_counter);
  }

  @override
  void initState() {
    //监听Bloc里的数据
    bloc.counter.listen((_count) {
      //设置状态值
      setState(() {
        _counter = _count;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bloc示例'),
      ),
      body: Center(
        child: Text(
          '$_counter',
          style: Theme.of(context).textTheme.display1,
        ),
      ),
      //增加按钮
      floatingActionButton: FloatingActionButton(
        //点击事件
        onPressed: _incrementCounter,
        child: Icon(Icons.add),
      ),
    );
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可鸭~

想吃糖~我会甜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值