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

目录
  • 前言
  • 使用方式
  • 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 更新事件同步异步的资料请关注我们其它相关文章!

(0)

相关推荐

  • flutter实现更新弹窗内容例子(亲测有效)

    什么是Flutter Flutter 是谷歌推出的开发移动UI框架,可以快速的在IOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作,并且Flutter是完全免费的,开源的. 总结来说: Flutter是一款移动应用程序SDK,包含框架.widget和工具,为开发人员提供了一种在Android和iOS上构建和部署精美移动应用程序的简单高效的方式. Flutter的优势 快速开发 毫秒级的热重载,修改后,您的应用界面会立即更新.使用丰富的.完全可定制的widg

  • Flutter之自定义Dialog实现版本更新弹窗功能的实现

    功能点: 1.更新弹窗UI 2.强更与非强更且别控制 3.屏蔽物理返回键(因为强更的时候点击返回键,弹窗会消失) 4.点击弹窗外透明区域时,弹窗不消失 先看下效果图: Dialog实现代码: import 'package:flutter/material.dart'; import 'package:xiaopijiang/utils/assets_util.dart'; import 'package:xiaopijiang/utils/toast_util.dart'; ///create

  • Flutter状态管理Bloc之登录示例

    本文实例为大家分享了Flutter状态管理Bloc之登录的具体代码,供大家参考,具体内容如下 1. 依赖 dependencies:   flutter_bloc: ^2.1.1   equatable: ^1.0.1 2. UserRepository 用于管理用户数据 提供认证方法,删除Token,保存Token,是否包含Token四个方法. import 'package:flutter/material.dart';   /// 用户数据仓库 class UserRepository {

  • Flutter状态管理Bloc之定时器示例

    本文实例为大家分享了Flutter状态管理Bloc之定时器的具体代码,供大家参考,具体内容如下 1. 依赖 dependencies:   flutter_bloc: ^2.1.1   equatable: ^1.0.1   wave: ^0.0.8 2. Ticker Ticker 用于产生定时器的数据流. /// 定时器数据源 class Ticker {      /// 定时器数据源   /// @param ticks 时间   Stream<int> tick({int ticks

  • Flutter状态管理Bloc使用示例详解

    目录 前言 两种使用模式 Cubit模式 最后 前言 目前Flutter三大主流状态管理框架分别是provider.flutter_bloc.getx,三大状态管理框架各有优劣,本篇文章将介绍其中的flutter_bloc框架的使用,他是bloc设计思想模式在flutter上的实现,bloc全程全称 business logic ,业务逻辑的意思,核心思想就是最大程度的将页面ui与数据逻辑的解耦,使我们的项目可读性.可维护性.健壮性增强. 两种使用模式 首先第一步引入插件: flutter_bl

  • Flutter如何轻松实现动态更新ListView浅析

    目录 前言 数据集 触发器 展示视图 完整代码 总结 前言 在 App 开发过程中,ListView 是 比较很常见的控件,用来处理 列表类的数据展示.当然 Flutter 也是支持的,由于 Flutter 是归属于声明式 UI 编程,其处理起来要更加的简单与便捷. 本文将通过一个极简单的例子来说明一下 如何 实现动态更新数据. 在贴代码之前,先介绍一些概念和内容 数据集 final _names = ['Andrew', 'Bob', 'Charles']; int _counter = 0;

  • Flutter下载更新App的方法示例

    1. 说明 iOS 和Android 更新是完全不一样的. iOS 只能跳转到 AppStore,比较好实现 Android则需要下载apk包,由于Android机型较多,这里我们用 dart 连接第三方(这里)的原生 android 下载库. 更新界面和下载更新分开处理的. iOS 没得下载进度这一说,Android 则有. 2. 代码 2.1 iOS 直接采用url_launcher就可以了 if (Platform.isIOS) { final url = "https://itunes.

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

    目录 前言 使用方式 Bloc 新形态用法 事件队列的阻塞属性? 前言 最近,小轰参与了公司 flutter 项目关于 Dart 2.0 的空安全升级工作.我们升级了所有依赖的三方库,其中就包括有 Bloc 库.作为一款使用率颇高的状态管理框架, Bloc 在版本迭代中进行了少许结构和细节的优化,下面是小轰对于 Bloc 新版本的使用总结. 使用方式 小轰使用的 Bloc 版本如下 flutter_bloc: ^7.3.1 通过最简单的例子来学习新知识 创建一个包含 加 减 操作的页面,使用 b

  • jquery中的ajax同步和异步详解

    之前一直在写JQUERY代码的时候遇到AJAX加载数据都需要考虑代码运行顺序问题.最近的项目用了到AJAX同步.这个同步的意思是当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,页面出去假死状态,当这个AJAX执行完毕后才会继续运行其他代码页面假死状态解除. 而异步则这个AJAX代码运行中的时候其他代码一样可以运行. jquery的async:false,这个属性 默认是true:异步,false:同步. $.ajax({ type: "post", url: "

  • Spring的事件和监听器-同步与异步详解

    目录 Spring的事件和监听器-同步与异步 1.首先新建StartWorkflowEvent.java, 2.新建一个监听器StartWorkflowListener.java 3.创建一个事件发布类EventPublisher.java 4.相关的配置 Spring事件.异步监听 这可以对系统进行解耦 Spring的事件和监听器-同步与异步 Application下抽象子类ApplicationContextEvent的下面有4个已经实现好的事件 ContextClosedEvent(容器关

  • jQuery中的ajax async同步和异步详解

    项目中有这样一个需求,使用ajax加载数据返回页面并赋值,然后前端取出该值 这其中涉及到代码的顺序问题,有时后台还未返回数据,但已执行后面代码, 所以就会造成取不到值 $.ajax({ type: "post", url: "admin/PfmOptionRuleItem.do", success: function(data){ $("#ruleItem").val(data.ruleItem); //① } }); return $(&quo

  • Java系统中拆分同步和异步详解

    前言 很多开发人员说,将应用程序切换到异步处理很复杂.因为他们有一个天然需要同步通信的Web应用程序.在这篇文章中,我想介绍一种方法来达到异步通信的目的:使用一些众所周知的库和工具来设计他们的系统. 下面的例子是用Java编写的,但我相信它更多的是基本原理,同一个应用程序可以用任何语言来重新写. 所需的工具和库: Spring Boot RabbitMQ 1.Web应用程序 一个用Spring MVC编写的Web应用程序并运行在Tomcat上. 它所做的只是将一个字符串发送到一个队列中 (异步通

  • Android xUtils更新到3.0后的基本使用规则详解

    说实话,对于xUtils,是我最近才用到的开发框架(也是刚接触),对于其功能不得不说,简化了很多的开发步骤,可以说是非常好的开发工具,但是其最近更新到3.0也没有解决加载自定义ImageView报错的问题. xUtils简介 xUtils 包含了很多实用的android工具. xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响... xUitls 最低兼容android 2.2 (api level 8) 我总是喜欢用

  • 对Python协程之异步同步的区别详解

    一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异步的性能区别,可以看到异步直接同时执行并完成, # 而同步,需要等待第一个完成后再次执行下一个,是有顺序的执行,而异步不需要 import time def task(pid): gevent.sleep(0.5) print('Task %s done' % pid) def task2(pid)

  • Flutter EventBus事件总线的应用详解

    目录 前言 EventBus的简介 EventBus的实际应用 总结 前言 flutter项目中,有许多可以实现跨组件通讯的方案,其中包括InheritedWidget,Notification,EventBus等.本文主要探讨的是EventBus事件总线实现跨组件通讯的方法. EventBus的简介 EventBus的核心是基于Streams.它允许侦听器订阅事件并允许发布者触发事件,使得不同组件的数据不需要一层层传递,可以直接通过EventBus实现跨组件通讯. EventBus最主要是通过

  • Android端内数据状态同步方案VM-Mapping详解

    目录 背景 问题拆解 目标 方案调研 EventBus 基于k-v的监听.通知 全局共享数据Model实例 基于注解的对象映射方案VM-Mapping 特点 思考 突破View层级的限制 突破类型的限制 详细设计 映射 数据驱动UI 总体流程 其它细节 方案对比 方案收益 后续计划 背景 西瓜在feed.详情页.个人主页有一块功能区,包括了点赞.收藏.关注等功能.这些功能长久以来都是孤立的:多个场景下点赞.收藏.关注等状态或数量不一致.在以往的业务迭代中,都是业务A有了需求,就加个点赞的请求,把

  • Flutter开发之对角棋游戏实现实例详解

    目录 前沿 演示效果 对角棋规则 实现思路 具体实现 1. 绘制棋盘 2. 绘制棋子 3. 手势处理 4. 游戏规则 优化 总结 前沿 关于对角棋相信大家都不陌生,其凭借着规则简单又灵活多变成为我们童年不可缺少的益智游戏. 今天我将用Flutter来实现一个对角棋游戏,即巩固自己Flutter的绘制和手势知识,也希望这篇文章对大家有所帮助. 演示效果 老规矩,我们先演示下实现的最终效果: 对角棋规则 首先我们还是回顾下对角棋游戏的规则,这里借用 百度百科 的规则说明: 棋盘:象棋棋盘中,将士所在

随机推荐