官术网_书友最值得收藏!

2.9 Events

Node的Events模塊只定義了一個類,就是EventEmitter(以下簡稱Event),這個類在很多Node本身以及第三方模塊中大量使用,通常是用作基類被繼承。

在前面的內容里我們已經接觸了很多關于事件處理的概念了,在Node中,事件的應用遍及代碼的每一個角落。

2.9.1 事件和監聽器

Node程序中的對象會產生一系列的事件,它們被稱為事件觸發器(event emitter),例如一個HTTP Server會在每次有新連接時觸發一個事件,一個Readable Stream會在文件打開時觸發一個事件等。

所有能觸發事件的對象都是EventEmitter類的實例。EventEmitter定義了on方法,該方法的聲明如下:

下面是一個事件注冊和觸發事件的例子。

代碼2.24 注冊一個事件并觸發它

上面的代碼中,首先初始化了一個EventEmitter實例,然后注冊了一個名為begin的事件,之后調用emit方法觸發了這一事件。

用戶可以注冊多個同名的事件,在上面的例子中,如果注冊兩個名為begin的事件,那么它們都會被觸發。

如果想獲取當前的emitter一共注冊了哪些事件,可以使用eventNames方法。

該方法會輸出包括全部事件名稱的數組。

就算注冊了兩個同名的event,輸出結果也只有一個,說明該方法的結果集并不包含重復結果。

注意:在Node v6.x及之前的版本中,event模塊可以通過:

引入,在新的版本中這種寫法已經被廢棄并會拋出一個異常,只能統一由require進行引入,有時能在一些舊版本的第三方模塊中還能看到。

2.9.2 處理error事件

由于Node代碼運行在單線程環境中,那么運行時出現的任何錯誤都有可能導致整個進程退出。利用事件機制可以實現簡單的錯誤處理功能。

當Node程序出現錯誤的時候,通常會觸發一個錯誤事件,如果代碼中沒有注冊相應的處理方法,會導致Node進程崩潰退出。例如:

上面的代碼主動拋出了一個error,相當于:

Node程序會打印出整個錯誤棧:

如果我們不想因為拋出一個error而使進程退出,那么可以讓uncaughtException事件作為最后一道防線來捕獲異常。

代碼2.25 使用uncaughtException事件捕獲異常

這種錯誤處理的方式雖然可以捕獲異常,避免了進程的退出,但不值得提倡,我們會在錯誤處理一章詳細介紹相關的內容。

Event模塊還有一些其他的API,這里不再一一介紹。

2.9.3 繼承Events模塊

在實際的開發中,通常不會直接使用Event模塊來進行事件處理,而是選擇將其作為基類進行繼承的方式來使用Event,在Node的內部實現中,凡是提供了事件機制的模塊,都會在內部繼承Event模塊。

以fs模塊為例,下面是其源碼中的一部分:

可以看出fs模塊通過util.inherit方法繼承了Event模塊。

假設我們要用Node來開發一個網頁上的音樂播放器應用,關于播放和暫停的處理,就可以考慮通過繼承events模塊來實現。

另一種場景,假設我們想要利用原生的數組來模擬一個消息隊列,該隊列會在新增消息和彈出消息時觸發對應的事件,也可以考慮繼承Events模塊。

詳細的內容可以參考第6章。

主站蜘蛛池模板: 永顺县| 上思县| 黎川县| 垦利县| 嵩明县| 额敏县| 旬邑县| 秀山| 峨山| 三江| 班戈县| 安龙县| 罗源县| 海宁市| 峨边| 古蔺县| 潞西市| 龙川县| 林西县| 景宁| 革吉县| 武鸣县| 闽侯县| 体育| 德令哈市| 江陵县| 玉山县| 罗平县| 海门市| 九龙坡区| 昭通市| 沿河| 建阳市| 临泽县| 枞阳县| 万源市| 鄂托克前旗| 正宁县| 秦皇岛市| 湘潭县| 宜宾县|