实习期结束,最近回到学校开始学习node.js,node果真是强大。不过在涉及到文件操做的时候,发现要大量使用异步回掉操做。node
之前在写页面的时候,从没这么多异步操做,只有在使用'setInterval'和'XMLHttpRequest'时了解了一下异步编程。此次在学习node的过程当中,把异步回掉算是弄清楚了。可是在编码书写代码的时候,陷入了回调金字塔(callback hell)。使用es6Promise解决了一些问题。也看到了EventProxy模块基于事件驱动的解决方案。es6
在使用EventProxy的过程当中,有种似曾相识的感受。有点像观察者模式发布/订阅。首先使用数组缓存订阅者订阅的消息,当订阅者订阅消息的时候,把订阅的消息push到指定消息的队列中,当发布者发布消息的时候,咱们遍历执行push到指定消息队列中的回调事件。编程
而订阅者不须要关心发布者何时发布消息。
而发布者不须要关心订阅者订阅的状态。数组
var observer = new Observe(); var callback = function(num) { console.log("event:"+num); // 输出event:2 }; // 订阅消息 observer.listen("event1", callback); observer.listen("event2", callback); // 移除订阅消息1 observer.remove('event1', callback); // 发布者发布消息 observer.trigger("event1",1); observer.trigger("event2",2);
具体代码以下:缓存
function Observe() { // 缓存订阅者的消息队列 this._list = []; } /** * * 订阅者订阅消息 * @param {string} key 消息名 * @param {Function} fn 回调事件 * @return {Null} */ Observe.prototype.listen = function(key, fn) { if (!this._list[key]) { this._list[key] = []; } // 订阅消息,添加到缓存列表中 this._list[key].push(fn); }; /** * * 移除订阅的消息 * @param {string} key 消息名 * @param {Function} fn 回掉事件 * @return {Null} */ Observe.prototype.remove = function(key, fn) { // 获取当前key下的消息记录 var arrFn = this._list[key]; if (!arrFn) return false; // 未指定fn则删除当前key下全部的订阅消息 if (!fn) { arrFn.length = 0; } else { for (var i = 0; i < arrFn.length; i++) { if (fn === arrFn[i]) { arrFn.splice(i,1); } } } }; /** * 发布者发布消息 * @param {string} key 消息名 * @param {string | Object} 消息数据 * @return {Null} */ Observe.prototype.trigger = function() { // 获得key,第二个及以上的参数 var key = Array.prototype.shift.call(arguments); var args = arguments; var arrFn = this._list[key]; if (!arrFn || arrFn.length === 0) { return; } // 遍历执行当前key下面的全部消息 for (var i = 0; i < arrFn.length; i++) { arrFn[i].apply(this, args); } };