博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Make a simple custom EventEmitter
阅读量:7175 次
发布时间:2019-06-29

本文共 3906 字,大约阅读时间需要 13 分钟。

Thoughts

Recently I have been reading the book about JS asynchronicity and JS event is one of the useful solutions to the problem. To get a deeper understanding of how events work, I create a custom EventEmitter which constains most of the working functionalities of . The is no more than 60 lines.

General ideas

The general ideas is to have an object (this.handlers) to hold the mapping from event name(type: string) to its associated listeners/handlers(type: Array<Function>). When each event is triggerd, walk through the associated listeners/handlers and execute them.

class Emitter {    constructor(){        /**         * keep mapping information。         * e.g.          *   {         *      'event1': [fn1, fn2],         *      'event2': [fn3, fn4, fn5]         *   }         */        this.handlers = {};    }}

Some details about the methods

on - event binding

on(evt, handler) {    this.handlers[evt] = this.handlers[evt] || [];    let hdl = this.handlers[evt];    hdl.push(handler);    return this;}

We don't check the duplicates when binding the handler for simplicity. That is to say, if you call on for the same function twice, then it will be called twice when the event is triggered. The method returns this to allow for method chaining。

off - event unbinding

removeListener(evt, handler) {    this.handlers[evt] = this.handlers[evt] || [];    let hdl = this.handlers[evt];    let index = hdl.indexOf(handler);    if(index >= 0) {        hdl.splice(index, 1);    }    return this;}

Note that here we compare the function reference with strict comparision when unbinding a function. Function in Javascript is compared by their reference, same as how objects comparision works.

function f1() {    console.log('hi');}function f2() {    console.log('hi');}let f3 = f1;console.log(f1 === f2); //falseconsole.log(f1 === f3); //true

once - binding, but only can be triggerd once

once(evt, handler) {    this.handlers[evt] = this.handlers[evt] || [];    let hdl = this.handlers[evt];    hdl.push(function f(...args){        handler.apply(this, args);        this.removeListener(evt, f);    });    return this;}

It works similarly with on method. But we need to wrap the handler with another function such that we can remove the binding once the handler is executed to achieve triggered only once.

emit - trigger event

emit(evt, ...args) {    this.handlers[evt] = this.handlers[evt] || [];    let hdl = this.handlers[evt];    hdl.forEach((it) => {        it.apply(this, args);    });    return this;}

When an event is triggered, find all its associated handlers(i.e. this.handlers[evt]) and execute them.

eventNames - get the list of registered events which has active(i.e. not-empty) handlers

eventNames() {    return Object.keys(this.handlers).reduce((arr, evt) => {        if(this.listenerCount(evt)) {            arr.push(evt);        }        return arr;    }, []);}

Here we don't simply return all the keys of the this.handlers , as some events can be binded with some handlers and then remove them afterwards. In the case, the event name exists as a valid key in this.handlers but without active handlers. E.g.

let server = new Emitter();let fn = function(){};server.on('connection', fn);server.removeListener('connection', fn);server.handlers.connection; //[]

Therefore, we need to filter out the events with empty hanlders. Here we use to make the code a little bit cleaner. There are many situations where reduce can be useful, such as computing the sum of an array:

function sumWithForEach(arr) { // with forEach    let sum = 0;    arr.forEach(it => {        sum += it;    })    return sum;}function sumWithReduce(arr) { // with reduce    return arr.reduce((sum, current) => {        return sum + current;    })}

Reference

Notice

  • If you benefit from this ,Please「Star 」to Support.
  • If you want to follow the latest news/articles for the series of reading notes, Please 「Watch」to Subscribe.

转载地址:http://fzdzm.baihongyu.com/

你可能感兴趣的文章
Windows Azure HandBook (3) 浅谈Azure安全性
查看>>
div+css布局入门
查看>>
Linux 下Apache和Resin的安装
查看>>
HDU 2710 Max Factorv (素数模板 & 多种解法)
查看>>
Linux 启动流程
查看>>
获得汉字字符串的首个拼音字母的缩写
查看>>
RegularExpressionValidator控件与常用验证正则表达式大全小结
查看>>
Zookeeper集群的安装和使用
查看>>
remobject 簡介
查看>>
一些Xcode快捷键,给新手
查看>>
DelayQueue在容错时的使用
查看>>
内联表达式
查看>>
Known Issues
查看>>
文件相关操作工具类——FileUtils.java
查看>>
原:视频直播技术中的参考技术网页
查看>>
linq教程
查看>>
requests从api中获取数据并存放到mysql中
查看>>
23种设计模式之组合模式(Composite)
查看>>
button按钮点击不刷新(前端交流学习:452892873)
查看>>
安卓 使用Gradle生成正式签名apk文件
查看>>