flutter中event_bus实现原理

Event Bus在江湖中的哪些血雨腥风

Event Bus可以说是在客户端界公认的最好的全局通信解决方案了,他的出现简化了应用程序内各组件间、组件与后台线程间的通信。

Event Bus可以说在各大端都有过实现:

Android端的Event Bus

compile 'de.greenrobot:eventbus:3.0.0-beta1'

Ios端的Event Bus

github "cesarferreira/SwiftEventBus" == 3.0.0

Vue更是直接就自带一个EventBus,简直不能再凶残了。那么,既然Event Bus这么不可或缺,Flutter平台肯定也有Event Bus了,对,绝逼是有的。

dependencies:
  event_bus: ^1.0.1

Flutter中EventBus 的实现原理

源码

class EventBus {
  StreamController _streamController;

  /// Controller for the event bus stream.
  StreamController get streamController => _streamController;

  /// new event bus
  EventBus({bool sync: false}) {
    _streamController = new StreamController.broadcast(sync: sync);
  }
  ///Listener
  Stream<T> on<T>() {
    if (T == dynamic) {
      return streamController.stream;
    } else {
      return streamController.stream.where((event) => event is T).cast<T>();
    }
  }
  /// Fires a new event on the event bus with the specified [event].
  void fire(event) {
    streamController.add(event);
  }
  /// Destroy this [EventBus]. This is generally only in a testing context.
  void destroy() {
    _streamController.close();
  }

很显然,你没有看错,源码就是这么少,相信之前用Rxjava做过RxBus这种风骚操作的你对这么几行代码实现一个Event Bus的你一点都不会觉得惊讶。

而Dart上可以凭借这么几行代码就实现一个Event Bus,同样的道理,背后有着一个分非常有气场的男人在支持,这个男人就是Stream。首先来看一看Event bus的创建。

Event bus的创建

EventBus({bool sync: false}) {
    _streamController = new StreamController.broadcast(sync: sync);
  }

创建的过程丢在了构造函数中,使用了broadcast方式,那么什么是broadcast方式呢?要了解这个,还需要知道StreamController的其他方式:

  1. Single subscription streams
  2. broadcast stream

所谓的single方式,是指这种stream流只能被一个人订阅,适用场景是http请求这种。

所谓的broadcast方式,是指这种stream流可以被多个人订阅,but,在你订阅之前的stream已经发送过得事件,你将错过了,只能收到你订阅开始之后发送的事件了。

streamController是dart的内置的一个类,可以理解为给stream制造数据的控制器,公开的方法add(Event)就是干这个的。

当然,这里提到了订阅,那么什么事订阅是怎么做的。

订阅

///Listener
  Stream<T> on<T>() {
    if (T == dynamic) {
      return streamController.stream;
    } else {
      return streamController.stream.where((event) => event is T).cast<T>();
    }
  }

这里使用泛型T来过滤自己想关心的事件类型,streamController成员stream中holder住了streamContorller制造出来的数据,一定订阅发送,这些数据将一个个的被发送出去,✔️的,每个订阅者都能得到这份数据流。

发送事件

发送事件很简单,就是使用streamController.add方法往stream中塞事件。

以上就是整个dart实现的event_bus的原理了,用一幅图来解释就是:

fires表示通过StreamController向Streams 中add Event,一旦有了event,subScriptor就嗅到了有货了,于是就取到了fires发送出来的event了。

关于Stream

Stream实际上类比Rxjava的话,就有点类似于Rxjava被订阅之前的那一段。是一个可以被订阅的流,因此,它也有一些比较风骚的操作,比如:

map

Stream<S> map<S>(S Function(T event) convert);

asyncMap

Stream<E> asyncMap<E>(FutureOr<E> Function(T event) convert);

当然,实际上用的最多还是

listen,实际上就是订阅,看其返回值就知道,是StreamSubsciption

StreamSubscription<T> listen(void Function(T event) onData,
    {Function onError, void Function() onDone, bool cancelOnError});

因此,如果想取消订阅的话,可以通过StreamSubsciption.cancel来做。这点都是可以我们熟悉的Rxjava类似。

事实上,stream在platform_channel中也有着其举足轻重的地位,做过的同学应该知道EventChannel实际上就是通过stream来实现的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

phpjiami 数种解密方法

Pwnhub公开赛出了个简单的PHP代码审计题目,考点有两个: 如果说仅为了做出题目拿到flag,这个题目太简单,后台也有数十名选手提交了答案和writeup。...

6007
来自专栏用户2442861的专栏

python lmdb使用

学习LMDB的时候不禁想到知乎上的提问“有哪些名人长期生活在其他名人的光环下”,说实话感觉查它的人基本都是为了用Caffe……

6472
来自专栏极客慕白的成长之路

信息安全实验室招新试题和完全解析

写个网页应该是很简单的,不管是静态网页还是带特效的网页。但是有几个问题,需要说明一下。

1133
来自专栏java一日一条

如何提高 Java 中锁的性能

两个月前向Plumbr公司引进线程死锁的检测之后,我们开始收到一些类似于这样的询问:“棒极了!现在我知道造成程序出现性能问题的原因了,但是接下来该怎么做呢?”

931
来自专栏BaronTalk

在Android项目中使用Java8

前言 在过去的文章中我介绍过Java8的一些新特性,包括: Java8新特性第1章(Lambda表达式) Java8新特性第2章(接口默认方法) Java8新特...

3116
来自专栏java一日一条

编写可靠 Shell 脚本的 8 个建议

这八个建议,来源于键者几年来编写 shell 脚本的一些经验和教训。事实上开始写的时候还不止这几条,后来思索再三,去掉几条无关痛痒的,最后剩下八条。毫不夸张地说...

1062
来自专栏架构之路

追源索骥:透过源码看懂Flink核心框架的执行流程

写在最前:因为这篇博客太长,所以我把它转成了带书签的pdf格式,看起来更方便一点。想要的童鞋可以到我的公众号“老白讲互联网”后台留言flink即可获取。

2.7K4
来自专栏一个番茄说

函数响应式编程框架RxSwift 学习——Observable

最近开始研究RxSwift,网上能查到的资料太有限,边学边记录,有不对的地方欢迎大家指正。

941
来自专栏PhpZendo

没错,这就是面向对象编程(设计模式)需要遵循的 6 个基本原则

在讨论面向对象编程和模式(具体一点来说,设计模式)的时候,我们需要一些标准来对设计的好还进行判断,或者说应该遵循怎样的原则和指导方针。

962
来自专栏美团技术团队

Android热更新方案Robust

美团•大众点评是中国最大的O2O交易平台,目前已拥有近6亿用户,合作各类商户达432万,订单峰值突破1150万单。美团App是平台主要的入口之一,O2O交易场景...

4189

扫码关注云+社区

领取腾讯云代金券