前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >flutter中event_bus实现原理

flutter中event_bus实现原理

原创
作者头像
brzhang
修改2018-09-13 18:32:31
9.3K0
修改2018-09-13 18:32:31
举报
文章被收录于专栏:玩转全栈玩转全栈

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

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

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

Android端的Event Bus

代码语言:javascript
复制
compile 'de.greenrobot:eventbus:3.0.0-beta1'

Ios端的Event Bus

代码语言:javascript
复制
github "cesarferreira/SwiftEventBus" == 3.0.0

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

代码语言:javascript
复制
dependencies:
  event_bus: ^1.0.1

Flutter中EventBus 的实现原理

源码

代码语言:javascript
复制
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的创建

代码语言:javascript
复制
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)就是干这个的。

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

订阅

代码语言:dart
复制
///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

代码语言:javascript
复制
Stream<S> map<S>(S Function(T event) convert);

asyncMap

代码语言:javascript
复制
Stream<E> asyncMap<E>(FutureOr<E> Function(T event) convert);

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

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

代码语言:javascript
复制
StreamSubscription<T> listen(void Function(T event) onData,
    {Function onError, void Function() onDone, bool cancelOnError});

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

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Event Bus在江湖中的哪些血雨腥风
  • Flutter中EventBus 的实现原理
    • 源码
      • Event bus的创建
        • 订阅
          • 发送事件
            • 关于Stream
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
            http://www.vxiaotou.com