EventEmitter 项目实战

作者: Kenny锅 | 来源:发表于2019-03-30 11:26 被阅读54次

1.Background

现有 APP 底部有 4 个 Tab 栏,Tabs 被一个类似 Frame 的页面包着,为了考虑性能与减少网络请求次数,只是首次进入会加载会 Tab 里的数据,所以QA与用户疯狂切 Tab,都是不请求数据,也不 rerender,真的如丝般顺滑。

2.New feature

好景不长,有一个带状态的列表要加入Tab 栏里来,列表有类似于「已购买」、「未购买」的状态,我们在详情页购买了,返回来要更新列表。

3.Motivation

第一时间想到的是 Redux ?很好,还有不同方案吗?对,就是 EventEmitter。

Redux 已经在我们现有项目中大量使用,已经觉得很无趣了。我们试试EventEmitter 怎么样? Node.js 源码里有很多地方都会使用 EventEmitter,例如:net.Server 会在每次有新连接时触发事件,fs.ReadStream 会在打开文件时触发事件,stream 会在数据可读时触发事件等。

我们为何不也学习一下呢? Come on, go ahead

4.Code

A、React Native 中的用法

1、在项目入口文件处引用 import EventEmitter from 'EventEmitter'; ,React Native 已经内置了这个类,源码地址:node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js
2、在项目入口文件(如:app.js 或 index.js)的 componentDidMount 里添加 global.CustomEventEmitter = new EventEmitter();
3、在 Tab 页的 componentDidMount 里添加 Listener,global.CustomEventEmitter.addListener('tabListClick', this.getLatestData);
4、在 Tab 页的 componentWillUnmount 里删除 Listener,global.CustomEventEmitter.removeListener('tabListClick', this.getLatestData);
5、在 Detail 页面如果购买了,就调用global.CustomEventEmitter.emit('tabListClick');

到这里用法已经就介绍完了,接下来简单介绍一下 EventEmitter 常用的 API:

  • addListener(eventType: string, listener: Function, context: ?Object)
    • eventType 为「事件名称」
    • listener 是一个回调的 function
    • context 表示 listener 调用时的上下文
  • removeListener(eventType: String, listener)
    • eventType 为「事件名称」
    • listener 是一个回调的 function
  • emit(eventType:string),传入一个「事件名称」

注意:eventType 要保持一致,并且区别大小写

其它 API 接口:
  • constructor(subscriber: ?EventSubscriptionVendor)
  • once(eventType: string, listener: Function, context: ?Object)
  • removeAllListeners(eventType: ?string)
  • removeCurrentListener()
  • removeSubscription(subscription: EmitterSubscription)
  • listeners(eventType: string)
B、Node.js 中的用法
  • 在 Node.js 项目里的引用方式稍有不同 ,是const EventEmitter = require('events');
  • 在 Node.js 用了 on 做为 addListener 的别名,也就是说 on('eventName') == addListener('eventName')
  • 同理,用了 off 做为 removeListener 的别名,也就是说 off('eventName') == removeListener('eventName')
  • 调用时:emitter.emit('eventName');

示例代码如下:

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('eventName', (a, b) => {
  console.log(a, b, this);
  // 打印: a b {}
});
myEmitter.emit('eventName', 'a', 'b');

这个例子的事件可以反复调用,只需调用:myEmitter.emit('eventName', 'a', 'b');

如果你有一个场景是只需要执行一次事件(比如:记录项目首次启动),Node.js 也帮我们考虑进去了,如官方代码所示:

const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
// 打印: 1
myEmitter.emit('event');
// 不触发
Node.js 中 events 其它API:
更多 Node.js 文章

相关文章

  • EventEmitter 项目实战

    1.Background 现有 APP 底部有 4 个 Tab 栏,Tabs 被一个类似 Frame 的页面包着,...

  • Tips of using RxJS

    Async EventEmitter Oh EventEmitter is Angular extension, ...

  • EventEmitter 用法

    import EventEmitter from 'events';window.eventEmitter = n...

  • freeCodeCamp 旅途10 - 算法实战

    项目实战:回文检查器 项目实战:罗马数字转换器 项目实战:凯撒密码 项目实战:电话号码验证器 项目实战:收银机

  • emit,EventEmitter,subscribe,next

    1 EventEmitter 介绍 EventEmitter 是封装的Observable类 export cla...

  • Nodejs.2

    参考内容:Node.js EventEmitter 四、Node.js EventEmitter Node.js所...

  • nodejs的EventEmitter类

    EventEmitter 类events 模块只提供了一个对象: events.EventEmitter。Even...

  • Node.js EventEmitter

    EventEmitter 类 events 模块只提供了一个对象: events.EventEmitter。Eve...

  • EventEmitter

    events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是...

  • 02.node的events模块

    events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是...

网友评论

    本文标题:EventEmitter 项目实战

    本文链接:https://www.haomeiwen.com/subject/npyfbqtx.html