flutter Bloc 更新后事件同步与异步详解

 更新时间:2022年11月14日 15:36:31   作者:李小轰_Rex  
这篇文章主要为大家介绍了flutter Bloc 更新后事件同步与异步详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

最近,小轰参与了公司 flutter 项目关于 Dart 2.0 的空安全升级工作。我们升级了所有依赖的三方库,其中就包括有 Bloc 库。作为一款使用率颇高的状态管理框架, Bloc 在版本迭代中进行了少许结构和细节的优化,下面是小轰对于 Bloc 新版本的使用总结。

使用方式

小轰使用的 Bloc 版本如下

flutter_bloc: ^7.3.1

通过最简单的例子来学习新知识

  • 创建一个包含 操作的页面,使用 bloc 来操作 自增 自减 事件。
class _TestBlocPageState extends State<TestBlocPage> {
  late TestDartBloc _bloc;
  @override
  void initState() {
    super.initState();
    _bloc = TestDartBloc(TestDartState(0));
  }
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TestDartBloc, TestDartState>(
      bloc: _bloc,
      builder: (context, state) {
        return Column(
          children: [
            //显示当前的数字结果
            Text(state.num.toString()),
            TextButton(
                onPressed: () {
                  //进行自增操作
                  _bloc.add(IncreaseEvent());
                },
                child: Text('add')),
            TextButton(
                onPressed: () {
                  //进行自减操作
                  _bloc.add(ReduceEvent());
                },
                child: Text('reduce')),
          ],
        );
      },
    );
  }
}

Blocstateevent 模型定义如下

part of 'test_dart_bloc.dart';
/// Bloc state
class TestDartState {
  int num = 0;
  TestDartState(this.num);
}
part of 'test_dart_bloc.dart';
/// Bloc event
@immutable
abstract class TestDartEvent {}
//自增事件
class IncreaseEvent extends TestDartEvent{}
//自减事件
class ReduceEvent extends TestDartEvent{}

创建 Bloc ,重写 mapEventToState 接收事件流转状态流

import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
part 'test_dart_event.dart';
part 'test_dart_state.dart';
class TestDartBloc extends Bloc<TestDartEvent, TestDartState> {
  TestDartBloc(TestDartState state) : super(state);
  @override
  Stream<TestDartState> mapEventToState(TestDartEvent event) async* {
    if (event is IncreaseEvent) {
      await Future.delayed(Duration(seconds: 10));
      yield TestDartState(state.num + 1);
    } else if (event is ReduceEvent) {
      yield TestDartState(state.num - 1);
    }
  }
}

好了,直接运行如上代码,我们的demo就能完整的跑起来。但,以上的写法和低版本的 Bloc 完全一致,在经历高版本迭代后,Bloc 到底做了哪些优化呢?

Bloc 新形态用法

小轰在源码里看到,重写 mapEventToState 的使用方式已经被弃用了,会在将来的某个版本中彻底删除该 API

  /// **@Deprecated - Use on<Event> instead. Will be removed in v8.0.0**
  ///
  /// Must be implemented when a class extends [Bloc].
  /// [mapEventToState] is called whenever an [event] is [add]ed
  /// and is responsible for converting that [event] into a new [state].
  /// [mapEventToState] can `yield` zero, one, or multiple states for an event.
  @Deprecated('Use on<Event> instead. Will be removed in v8.0.0')
  Stream<State> mapEventToState(Event event) async* {}

新用法推荐使用 on 来进行事件注册,我们将上面demo中的 bloc 进行写法改造:

class TestDartBloc extends Bloc<TestDartEvent, TestDartState> {
  TestDartBloc(TestDartState state) : super(state) {
    init();
  }
  void init() {
    on<IncreaseEvent>((event, emit) async {
      await Future.delayed(Duration(seconds: 10));
      emit(TestDartState(state.num + 1));
    });
    on<ReduceEvent>((event, emit) {
      state.num - 1;
      emit(state);
    });
  }
}

替换代码后运行demo,直接成功。

事件队列的阻塞属性?

目前最新版本的 Bloc 同时支持 onmapEventToState 两种写法,那么这两种写法有实际区别吗?

小轰在使用老版本(空安全之前)bloc 时总结过一篇文章 聊聊 Bloc event 的队列属性

blocmapEventToState 方法中,event 队列是一个阻塞性队列,先进先出,只有当上一个事件消费完毕后,才会响应队列中的下一个事件。

如上demo( mapEventToState 方式): 自增事件中模拟耗时了10s,当依次点击 自增自减 按钮后,由于事件队列的阻塞特性,自增事件消费10秒后,自减事件才会被 mapEventToState 响应。

那么,这个特性在 bloc 迭代新版本后还存在吗?在最新版本的bloc中,小轰通过demo测试得出结论:

  • 当使用 mapEventToState 方式进行事件捕获时,event 队列 保持 阻塞 特性。
  • 而使用 on 方式进行注册监听时,event 队列 默认是异步非阻塞的,是互不干扰的。如果把 bloc 当作事件总线来使用,小轰认为 异步非阻塞 这样的设计更为合理。

提问:如果想使用 on 的方式进行注册,还想事件队列保证顺序执行即保持阻塞特性,应该怎么办呢? 解答:使用 自定义 transformer,这样就实现了事件同步队列。

    on<IncreaseEvent>((event, emit) async {
      await Future.delayed(Duration(seconds: 10));
      emit(TestDartState(state.num + 1));
    },
    transformer: (events, mapper) => events.asyncExpand(mapper),
);

参考链接: pub.dev/packages/bl…

以上就是flutter Bloc 更新后事件同步与异步详解的详细内容,更多关于flutter Bloc 更新事件同步异步的资料请关注脚本之家其它相关文章!

相关文章

  • 2014值得推荐的10个移动 Web 应用程序开发框架

    2014值得推荐的10个移动 Web 应用程序开发框架

    今天这篇文章向大家推荐10大优秀的移动 Web 开发框架,帮助开发者更加高效的开发移动Web应用。
    2014-08-08
  • Retrofit自定义请求参数注解的实现思路

    Retrofit自定义请求参数注解的实现思路

    这篇文章主要给大家介绍了Retrofit自定义请求参数注解的实现思路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • Android编程使用Intent传递对象的方法分析

    Android编程使用Intent传递对象的方法分析

    这篇文章主要介绍了Android编程使用Intent传递对象的方法,结合实例形式详细分析了Android使用Intent实现传递对象的相关技巧与注意事项,需要的朋友可以参考下
    2016-01-01
  • Android实战教程第一篇之最简单的计算器

    Android实战教程第一篇之最简单的计算器

    这篇文章主要为大家详细介绍了Android实战教程第一篇,如何实现最简单的计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Gradle编译打包Android apk详细介绍

    Gradle编译打包Android apk详细介绍

    这篇文章主要介绍了Gradle编译打包Android apk详细介绍的相关资料,理解Gradle构建过程,解读Android Gradle插件的配置,需要的朋友可以参考下
    2016-12-12
  • Android中ViewPager1和ViewPager2的使用教程

    Android中ViewPager1和ViewPager2的使用教程

    这篇文章主要介绍了Android中ViewPager1和ViewPager2的使用,效果图是结合BottomNavigationView+ViewPager一起使用的,具体实例代码跟随小编一起看看吧
    2021-10-10
  • InputFilter实现EditText文本输入过滤器实例代码解析

    InputFilter实现EditText文本输入过滤器实例代码解析

    EditText是Android的文本输入框控件。这篇文章给大家介绍 InputFilter实现EditText文本输入过滤器实例代码解析,需要的朋友一起看看吧
    2016-11-11
  • 深入理解Android M 锁屏密码存储方式

    深入理解Android M 锁屏密码存储方式

    下面小编就为大家带来一篇深入理解Android M 锁屏密码存储方式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Android中如何实现清空搜索框的文字

    Android中如何实现清空搜索框的文字

    本文主要介绍Android中实现清空搜索框的文字的方法。项目中的有关搜索的地方,加上清空文字的功能,目的是为了增加用户体验,使用户删除文本更加快捷。需要的朋友一起来看下吧
    2016-12-12
  • android RecyclerView的一些优化点介绍

    android RecyclerView的一些优化点介绍

    大家好,本篇文章主要讲的是android RecyclerView的一些优化点介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12

最新评论