您好,登錄后才能下訂單哦!
這篇文章主要介紹了怎么使用Node.js的內置模塊event實現(xiàn)發(fā)布訂閱模式的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇怎么使用Node.js的內置模塊event實現(xiàn)發(fā)布訂閱模式文章都會有所收獲,下面我們一起來看看吧。
引入event內置模塊
// 引入內置模塊event const EventEmitter = require("events");
創(chuàng)建event對象
event
內置模塊本質是一個構造函數,我們需要通過new
操作符去調用它
// 創(chuàng)建event對象 const event = new EventEmitter();
監(jiān)聽事件
使用event
對象上的on
函數來定義一個監(jiān)聽事件,語法為:event.on(事件名,事件處理函數)
// 監(jiān)聽run事件 event.on("run", (data) => { console.log("run事件運行,參數為:", data); });
觸發(fā)事件
使用event
對象上的emit函數來觸發(fā)監(jiān)聽的事件,語法為:event.emit(需要觸發(fā)的事件名,需要給事件處理函數傳遞的參數)
// 觸發(fā)run事件 event.emit("run", "111111");
完整代碼
// 引入內置模塊event const EventEmitter = require("events"); // 創(chuàng)建event對象 const event = new EventEmitter(); // 監(jiān)聽run事件 event.on("run", (data) => { console.log("run運行,參數為:", data); }); // 觸發(fā)run事件 event.emit("run", "111111");
運行結果:
?? 事件重復監(jiān)聽的問題
==注意:當同一事件被監(jiān)聽多次時,觸發(fā)事件時會同時觸發(fā)這個事件的所有事件處理函數==
Node.js | 搭建后端服務器(含內置模塊 http | url | querystring 的使用)中有一個使用node
模擬get
請求(轉發(fā)跨域數據)的案例:
const http = require("http"); const https = require("https"); // http和https的區(qū)別僅在于一個是http協(xié)議一個是https協(xié)議 const url = require("url"); const server = http.createServer(); server.on("request", (req, res) => { const urlObj = url.parse(req.url, true); res.writeHead(200, { "content-type": "application/json;charset=utf-8", "Access-Control-Allow-Origin": "http://127.0.0.1:5500", }); switch (urlObj.pathname) { case "/api/maoyan": // 我們定義的httpget方法:使node充當客戶端去貓眼的接口獲取數據 httpget((data) => res.end(data)); // 注意這里 break; default: res.end("404"); break; } }); server.listen(3000, () => { console.log("服務器啟動啦!"); }); function httpget(cb) { // 定義一個存放數據的變量 let data = ""; // 因為貓眼的接口是https協(xié)議的,所以我們需要引入https // http和https都具有一個get方法能夠發(fā)起get請求,區(qū)別是一個是http協(xié)議,一個是https協(xié)議 // http get方法第一個參數為接口地址,第二個參數為回調函數 https.get( "https://i.maoyan.com/api/mmdb/movie/v3/list/hot.json?ct=%E8%A5%BF%E5%8D%8E&ci=936&channelId=4", (res) => { // http get方法獲取的數據是一點點返回的,并不是直接返回全部 // 監(jiān)聽data,當有數據返回時就會被調用 res.on("data", (chunk) => { // 收集數據 data += chunk; }); // 監(jiān)聽end,數據返回完畢后調用 res.on("end", () => { cb(data); // 注意這里 }); } ); }
注意上面代碼的第19行和第49行:
httpget((data) => res.end(data)); // 注意這里
cb(data); // 注意這里
這個例子中,我們是通過在httpget
函數中傳入一個回調函數來接收httpget
函數獲取到的數據,這種寫法實際是沒有問題的,在開發(fā)中也常常進行使用。
但在一些情況下,特別是函數多層嵌套調用時(如下面的例子),這種寫法就顯得不夠優(yōu)雅,因為它的代碼結構不是很清晰,不能很直觀的看懂其邏輯:
function user() { getUser((data) => { console.log(data); }); } function getUser(cb) { // .... const id = 1; getUserInfo(cb, id); } function getUserInfo(cb, id) { // .... const name = id + "Ailjx"; cb(name); }
讓我們使用內置模塊event
去改造一下上面node
模擬get
請求(轉發(fā)跨域數據)的案例:
const http = require("http"); const https = require("https"); const url = require("url"); const EventEmitter = require("events"); const server = http.createServer(); // 存放event對象 let event = ""; server.on("request", (req, res) => { const urlObj = url.parse(req.url, true); res.writeHead(200, { "content-type": "application/json;charset=utf-8", "Access-Control-Allow-Origin": "http://127.0.0.1:5500", }); switch (urlObj.pathname) { case "/api/maoyan": event = new EventEmitter(); // 注意該位置 // 監(jiān)聽事件 event.on("resEnd", (data) => { res.end(data); }); httpget(); break; default: res.end("404"); break; } }); server.listen(3000, () => { console.log("服務器啟動啦!"); }); function httpget() { let data = ""; https.get( "https://i.maoyan.com/api/mmdb/movie/v3/list/hot.json?ct=%E8%A5%BF%E5%8D%8E&ci=936&channelId=4", (res) => { res.on("data", (chunk) => { data += chunk; }); res.on("end", () => { // 觸發(fā)事件并傳遞數據 event.emit("resEnd", data); }); } ); }
運行并調用/api/maoyan
接口:
接口正常使用
注意上邊代碼new EventEmitter()
的位置,如果new EventEmitter()
是在外部的話,相當于是只有一個全局的event
對象,當我們每次調用/api/maoyan
接口時,node
都會監(jiān)聽一個新的resEnd
事件,這就會導致resEnd
事件被重復監(jiān)聽:
所以我們才需要將創(chuàng)建event
對象的代碼new EventEmitter()
寫到接口的case
分支里,這樣當我們調用這個接口時,會創(chuàng)建一個新的event
對象,老的event
對象被棄用會被JS
垃圾處理機制給處理掉,這樣就不會出現(xiàn)resEnd
事件被重復監(jiān)聽的問題
關于“怎么使用Node.js的內置模塊event實現(xiàn)發(fā)布訂閱模式”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“怎么使用Node.js的內置模塊event實現(xiàn)發(fā)布訂閱模式”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。