怎么实现系列:9.怎么实现一个eventEmitter-下篇

108 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

系列介绍

经常会被面试官问到这个功能或者效果怎么实现,或者怎么实现xx功能/效果?

有些功能或者效果以前没有做过或者实现过,导致自己回答不出来,场面一度变得有些尴尬。

于是自己打算出一个怎么实现系列,来实现xx功能或者xx效果,以此来提升自己的实战效果和能力。

本系列是一个开放系列,可能自己能力有限,故我实现的效果或者代码不一定是最好的,欢迎大家参与交流讨论。

场景

面试官:有了解过eventEmitter吗?

我:有的,node里面的events模块就有一个eventEmitter类。eventEmitter类是node事件驱动系统的基础,可以用eventEmitter来监听或者触发事件,从而实现node的异步事件驱动架构。

面试官:你应该有使用过eventEmitter,那让你实现一个eventEmitter,你怎么实现?

(假装思考了一会)

我:这个,我虽然使用过eventEmitter,但是要说实现一个eventEmitter,倒是没有实现过。

面试官:...

查阅资料

eventEmitter,事件发布订阅系统。

我们可以利用eventEmitter来监听事件,当事件触发时,执行对应的回调函数。

我们也可以使用eventEmitter来触发事件。

eventEmitter既可以监听事件,也可以触发事件,是一种事件驱动机制。它的监听事件和触发事件,组成了一个事件发布订阅系统。

前言

怎么实现系列:8.怎么实现一个eventEmitter-上篇里,我们先是创建了一个eventEmitter类。

eventEmitter类创建好了,那么在下篇里,我们就要使用这个eventEmitter类了。eventEmitter类的每个方法都使用一下,看下能不能达到想要的效果。

使用

创建一个名字为index.html文件

先是创建一个script标签,引入我们在怎么实现一个eventEmitter-上篇里创建的eventEmitter类。

<script src="./index.js"></script>

再创建一个script标签,在script标签里,我们使用一下eventEmitter类的各个方法。

on

on方法,监听事件,绑定回调函数。


 emitter.on('getName',function(){
            console.log('getName事件触发了');
 })
emit

emit方法,触发事件


emitter.emit('getName')

运行index.html文件,到浏览器控制台查看打印信息

0001.png

我们可以看到,getName事件触发了。

以上是没有传递参数的,如果我们在emit的时候,传递参数会怎么样?

我们试一下,把上面的on监听事件和emit触发事件修改一下


emitter.on('getName',function(name){
            console.log(`获取名字:${name}`);
        })
        emitter.emit('getName','tom')

运行index.html文件,到浏览器控制台查看打印信息

0002.png

我们可以看到,参数被传递过去,并且使用了

removeListener

removeListener方法,移除监听事件的回调函数


emitter.on('sayHi',say)
function say(){
            console.log('打个招呼');
}
emitter.emit('sayHi')
emitter.removeListener('sayHi',say)
emitter.emit('sayHi')

运行index.html文件,到浏览器控制台查看打印信息

0003.png

我们可以看到,sayHi事件,触发了两次,但是控制台只打印了一次信息。

这是因为,我们第一次触发sayHi事件,然后用removeListener移除监听事件的回调函数。

再用emit触发sayHi事件,它的回调函数就没有执行了。

removeAllListener

removeAllListener方法,用来移除所有监听事件


emitter.on('sayHi',function(){
            console.log('打个招呼');
        })
emitter.on('getName',function(){
            console.log('获取名字');
})
emitter.removeAllListener()
emitter.emit('sayHi')
emitter.emit('getName')

运行index.html文件,到浏览器控制台查看打印信息

0004.png

我们可以看到,控制台没有打印信息。

我们先是用on方法监听事件,但是有用removeAllListener方法,把所有监听事件都给移除了。

再用emit方法触发事件,这时事件就没有触发

once

once方法,让监听事件的回调函数只执行一次


emitter.once('sayHi',function(){
            console.log('打个招呼');
        })
emitter.emit('sayHi')
emitter.emit('sayHi')

运行index.html文件,到浏览器控制台查看打印信息

0005.png

我们可以看到,虽然sayHi事件触发了两次,但是打个招呼只打印了一次

小结

我们创建了一个eventEmitter类,它有如下方法

  • on:监听事件
  • emit:触发事件
  • removeListener:移除监听事件的回调函数
  • removeAllListener:移除所有监听事件
  • once:监听事件的回调函数只执行一次

我们创建的eventEmitter类,和node里的eventEmitter实现的效果是一样的。

至此,怎么实现一个eventEmitter介绍完了。

最后,放上自己比较喜欢的一句诗句:

千淘万漉虽辛苦,吹尽狂沙始到金 - 唐 刘禹锡《浪淘沙》