實習期結束,最近回到學校開始學習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); } };