最近在琢磨javascript的自定义事件,我的理解是注册一个事件(addEvent),然后在需要的时候调用它(fireEvent),这感觉像声明好一个函数,然后在需要的时候调用,感觉不出它们之间的区别。
我觉得任何事物的存在都有它的道理,那这自定义事件到底用在哪些场景?
最近在琢磨javascript的自定义事件,我的理解是注册一个事件(addEvent),然后在需要的时候调用它(fireEvent),这感觉像声明好一个函数,然后在需要的时候调用,感觉不出它们之间的区别。
我觉得任何事物的存在都有它的道理,那这自定义事件到底用在哪些场景?
27 回答13k 阅读
8 回答3.5k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
5 回答5.3k 阅读✓ 已解决
4 回答1.6k 阅读✓ 已解决
6 回答1.1k 阅读
3 回答1.7k 阅读
你的感觉是对的,实际上事件机制就是从回调函数转化而来的。
实际上事件模式算是订阅/发布模式的一种,它的好处在于绑定事件和触发事件是互相隔离的,并且可以动态的添加和删除,下面我帮你一步一步的梳理出来。
现在有这么一个需求,首先,我有一个动作Action1,我想每次在Action1完成之后,都会触发一个服务Service1,那么代码我可以这么写。
这个就是楼主所想的,代码非常明了而且易懂,很不错。
然而现在需求来了,我的动作Action1,想在它完成以后,不仅能触发一个服务Service1,还能触发Service2,Service3……
你可能想到,应该声明另外一个叫ServiceAll的函数,然后在ServiceAll里依次调用Service1、Service2、Service3,这个主意是可行的。
但问题随之而来,这里的ServiceAll事先定义好了,假如我要动态的添加一个Service4怎么办?假如我突然改变心意,动作Action1以后不再执行Service2,这个时候代码正在运行,必须重新定义ServiceAll函数,这无论开销还是实现都不方便。
我们再换个思路,我们弄一个叫ServiceArray的数组,然后把所有要执行的Service都放进去,动作Action1以后,直接循环调用ServiceArray岂不是就好了?
好了,我们已经用数组队列来轻松实现动态删除和动态添加Service的功能了,接下来又有一个新的需求。
我们上面都是一个动作Action1,我现在有第二个动作Action2,它也要有一堆Service要执行,这个时候最简单的实现办法是和上面一样,但如果直接复制粘贴代码的话,动作一多,重复代码就太多了,所以为了代码复用,我们写个统一的处理函数
我们上面考虑的这些Action1,Action2都是相互独立的情况,下面再考虑一个问题,假设这些动作都是某个对象obj发出来的,我们必须要保证这个对象在Service1,Service2等等都能访问到,这个时候该怎么办?
你可能想到把obj带在handleAction的参数里,然后再其定义里由Servie(obj)带进去,这是可行的,不过我们换个面向对象的思路
看到这里,聪明的你应该就清楚了,我们是在实现一个简易的自定义事件机制,把其中的名字换一下就能更清晰的看出来了。
这样我们就能通过new一个EventEmitter来使用它了。
这个简单的事件对象已经可以满足我上面提到的种种要求了,但还缺少附加参数、移除所有事件、限定域等等功能,把这些完善以后,再优化一下事件队列的存储方式,你就完成了一个真正的EventEmitter了。
所以题主你应该明白了事件模式的好处了吧?