您现在的位置是:Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款 > 

04 js訂閱者模式和觀察者模式代碼(詳解如何模擬實現node中的Events模塊(通俗易懂版))

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款2024-05-23 00:12:17【】1人已围观

简介Emitter.emit('嗨','你好');#只能輸出一次你好實現思路:當once監聽的事件回調函數執行之后,通過removeListener將事件監聽器給解綁掉,那么事件再次被emit的時候,就不

Emitter.emit('嗨','你好'); #只能輸出一次你好

實現思路:當 once 監聽的事件回調函數執行之后,通過 removeListener 將事件監聽器給解綁掉,那么事件再次被 emit 的時候,就不會再次執行回調,這樣就能保證事件回調只能執行一次

once (eventName, listener) {

#重新改變監聽回調函數,使其執行之后可以被銷毀

let reListener = (...rest) => {

listener.apply(this,rest);

#執行完之后解除事件綁定

this.removeListener(type,wrapper);

}

this.on(eventName,reListener);

}

5. listeners 方法使用與實現

listeners 方法返回名為 eventName 的事件的監聽器數組的副本,其實就是獲取 eventName 中所有的回調函數,這個實現起來很容易,就不多贅述了,代碼如下:

listeners (eventName) {

return this.events[eventName]

}

6. setMaxListeners 方法使用與實現

默認情況下,如果為特定事件添加了超過 10 個監聽器,則 EventEmitter 會打印一個警告。 這有助于發現內存泄露, 但是,并不是所有的事件都要限制 10 個監聽器。 emitter.setMaxListeners() 方法可以為指定的 EventEmitter 實例修改限制。 值設為 Infinity(或 0)表示不限制監聽器的數量。

買粉絲nst EventEmitter = require('events');

class MyEmitter extends EventEmitter { }

買粉絲nst myEmitter = new MyEmitter();

let callback = (str) => {

買粉絲nsole.log(str);

}

for (let i = 0; i <= 11; i++) {

myEmitter.on('嗨', callback);

}

myEmitter.emit('嗨', '你好');

輸入結果如圖:

實現思路:

我們先將特定事件的監聽器最大設置為常量10

買粉絲nstructor(){

#事件監聽函數保存的地方

this.events={ };

#最大監聽器數量

this._maxListeners = 10;

}

然后在我們的 on 函數中,對這個監聽器的數量進行判斷,從而作出提示

on(eventName,listener){

if (this.events[eventName]) {

this.events[eventName].push(listener);

#如果超過最大限度,以及不為0,則作出內存泄漏提示

if (this._maxListeners != 0 && this.events[type].length >= this._maxListeners) {

買粉絲nsole.error('超過最大的監聽數量可能會導致內存泄漏');

}

} else {

#如果沒有保存過,將回調函數保存為數組

this.events[eventName] = [listener];

}

}

我們也支持對 _maxListeners 變量根據用戶的輸入進行更改,即我們的 setMaxListeners() 函數

setMaxListeners(MaxListeners) {

this._maxListeners = MaxListeners

}

三、總結

本文從 node 的 Events 模塊出發,然后去介紹了 Events 模塊常用 API 的使用,從中通過一步一步簡易去思考這些 API 使用的內部原理,簡易的實現了這些 API,希望大家看完文章之后,能對 Events 模塊有進一步的理解。

關于generator異步編程的理解以及如何動手寫

關于generator異步編程的理解以及如何動手寫一個買粉絲模塊

generator出現之前,想要實現對異步隊列中任務的流程控制,大概有這么一下幾種方式:

回調函數

事件監聽

發布/訂閱

promise對象

第一種方式想必大家是最常見的,其代碼組織方式如下:

請點擊輸入圖片描述

function fn(url, callback){ var 買粉絲Request;//創建XHR

買粉絲Request = window.XMLHttpRequest ? new XMLHttpRequest() :

window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : undefined;

 

買粉絲Request.onreadystatechange = function(){  if(買粉絲Request.readystate === 4 && 買粉絲Request.status === 200){ //狀態判斷   callback.call(買粉絲Request.responseXML);

 }

};

買粉絲Request.open("GET", url);

買粉絲Request.send();

}

fn("text.xml", function(){ //調用函數

買粉絲nsole.log(this); //此語句后輸出});

買粉絲nsole.log("this will run before the above callback.");//此語句先輸出

請點擊輸入圖片描述

對于一個普通的ajax異步請求來說,我么在請求開始的時候就要告訴他請求成功之后所要執行的動作,因此就可以類似以這種方式組織代碼,控制異步流程。這種調用方式最大的問題就是回調黑洞的問題,一層回調也還好,但涉及到二層、三層、n層的時候就讓代碼變得復雜很難維護。

第二種方式自己在前段時間使用backbone.js作為技術棧的項目的開發中深有體會,對于每一個ajax請求都對其分配一個自定義事件,在ajax成功返回數據的時候,就會觸發自定義的事件完成接下來的動作,控制異步流程,代碼如下:

請點擊輸入圖片描述

請點擊輸入圖片描述

第三種方式和第二種的方式性質上有些類似,如果從發布訂閱的角度來看,on方法相當于訂閱者/觀察者,trigger方法相當于發布者。原理上來說無非就是維護一個“消息中心”的數組,通過on方法訂閱的事件都會推入“消息中心”數組,最后發布的時候將會匹配“消息中心”數組的事件,進而執行相應的流程。

我們通過jquery的sub/pub插件完成一個很簡單的演示。

首先,f2向"信號中心"jQuery訂閱"done"信號。

請點擊輸入圖片描述

jQuery.subscribe("done", f2);

function f1(){

setTimeout(function () {

// f1的任務代碼

jQuery.publish("done");

}, 1000);

}

f1();

請點擊輸入圖片描述

jQuery.publish("done")的意思是,f1執行完成后,向"信號中心"jQuery發布"done"信號,從而引發f2的執行。

第四種方式promise范式,先看一段代碼:

請點擊輸入圖片描述

我們只要并且僅需要new一個promise對象,就會發現promise對象的參數函數已經執行了,隔兩秒之后輸出"執行完成"。

接下來再看一段其實際應用的場景代碼:

請點擊輸入圖片描述

從本質上來看,Promise是一個構造函數,其本身有all、reject、resolve等方法,同時其原型上有then、catch等方法。通過其用Promise new出來的對象自然就有then、catch方法。然后可以通過then方法中的回調函數,獲取到上一段異步操作中返回(通過resolve)的數據。從而實現對異步操作的流程控制。

但我的每個函數都得被promise對象包裝一下,同時一大堆的then...真是一個聽蛋疼的事兒...

綜上所述對于異步流程的控制,都有其自身的缺陷,我們最理想的方式便是像操作同步流程那樣實現對異步流程的控制,試想一下這樣的異步操作流程(加了層層包裝,proxy便是發送一個異步請求,接下來的代碼便是獲取到異步操作返回的數據,細節可暫時忽略):

請點擊輸入圖片描述

這感覺就是真他媽的舒服,怎么實現這么一個讓人很爽的東西呢,于是我們的主角---偉大的Generator函數登場了。

先理解這么自己悟的一句話:

"javascript是單線程的,順序執行一段代碼,執行到了異步操作,按正常的邏輯走的話就是主隊列中的代碼繼續執行,這時異步隊列中的代碼還未執行,我們繼續執行的代碼也就會發生報錯。那么解決問題的關鍵就是,我們能夠手動控制代碼的向下執行,配合一個東西監聽到異步操作的已經正常返回了之后,去手動的操作代碼的執行流程,這樣的話就實現了已同步的方式控制異步代碼的執行" 

那么問題變成了解決兩個問題。

1、我們是如何實現對于異步操作是否成功返回的監聽。

2、如何手動操作代碼的向下執行。

對于第一個問題,我們采用的方案是使用promise對象的方式,Promise 的編程思想便是,用于“當xx數據準備完畢,then執行xx動作”這樣的場景

很赞哦!(5876)

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款的名片

职业:程序员,设计师

现居:江西上饶上饶县

工作室:小组

Email:[email protected]