ホームページ >ウェブフロントエンド >フロントエンドQ&A >どのオブジェクトがnodejsのイベントモジュールによって提供されるか

どのオブジェクトがnodejsのイベントモジュールによって提供されるか

青灯夜游
青灯夜游オリジナル
2021-11-11 16:50:081535ブラウズ

nodejs では、イベント モジュール「events」は 1 つのオブジェクト「EventEmitter」のみを提供します。その中核となるのはイベントの発行とイベント リスナーです。このオブジェクトは複数のイベント リスナーをサポートしています。イベントが発行されると、このイベントに登録されているイベント リスナーが順番に呼び出され、イベント パラメーターがコールバック関数のパラメーターとして渡されます。

どのオブジェクトがnodejsのイベントモジュールによって提供されるか

このチュートリアルの動作環境: Windows7 システム、nodejs バージョン 12.19.0、Dell G3 コンピューター。

nodejs のイベント モジュール (イベント)

Events は、node.js の最も重要なモジュールです。イベント モジュールは、events.EventEmitter という 1 つのオブジェクトのみを提供します。EventEmitter の中核は、イベントの発行とイベントリスニングのデバイス。

Node.js のほとんどのモジュールは、Event モジュールから継承します。

DOM ツリー上のイベントとは異なり、イベントのバブリングやレイヤーごとのキャプチャはありません。

EventEmitter は、いくつかのイベント リスナーをサポートします。イベントが発行されると、このイベントに登録されているイベント リスナーが順番に呼び出され、イベント パラメータがコールバック関数のパラメータとして渡されます。

アクセス方法:

require('events');

emitter.on(event,listener)

/*
    调用events模块,获取events.EventEmitter对象
*/
var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

/*
    EventEmitter.on(event, listener) 为事件注册一个监听
    参数1:event  字符串,事件名
    参数2:回调函数
*/
ee.on('some_events', function(foo, bar) {
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
});

console.log('第一轮');
ee.emit('some_events', 'Wilson', 'Zhong');

console.log('第二轮');
ee.emit('some_events', 'Wilson', 'Z');

emitter.emit(event, [arg1] , [arg2], [...])

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {         
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
});/*
    EventEmitter.emit(event, [arg1], [arg2], [...])   触发指定事件
    参数1:event  字符串,事件名
    参数2:可选参数,按顺序传入回调函数的参数
    返回值:该事件是否有监听*/var isSuccess = ee.emit('some_events', 'Wilson', 'Zhong');

ee.on('some_events', function(foo, bar) {         
    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );
});

ee.emit('some_events', 'zhong', 'wei');var isSuccess2 = ee.emit('other_events', 'Wilson', 'Zhong');

console.log(isSuccess);
console.log(isSuccess2);

この例では、some_events が監視用に登録されている 3 つのトリガー イベント操作と、送信関数を実行します。 true を返し、other_events がリスナーを登録していない場合、emit 関数は false を返し、イベントが監視されていないことを示します。もちろん、この戻り値を無視することもできます。

emitter.once(event,listener)

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();/*
    EventEmitter.once(event, listener)  为事件注册一次性监听,触发一次后移除监听
    参数1:event  字符串,事件名
    参数2:回调函数*/ee.once('some_events', function(foo, bar) {
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
});


console.log('第一轮');
ee.emit('some_events', 'Wilson', 'Zhong');

console.log('第二轮');var isSuccess =  ee.emit('some_events', 'Wilson', 'Zhong');
console.log(isSuccess);

上記サンプルコードの実行結果からわかるように、 Emitter.once を使用する some_events のリスナーを登録した後、emitter.emit トリガーを 2 ラウンドで呼び出します。2 ラウンド目は false を返します。これは、emitter.once を使用したモニターの登録は、前述の Emitter.on を使用したモニターの登録とは少し異なることを意味します。先ほど、

emitter.once 登録されたモニタリングは 1 回限りのモニタリングであり、一度トリガーされるとモニタリングは削除されます。もちろん、名前から見ても明らかです^_^!

emitter.removeListener(event,listener)

まず、失敗したシナリオを見てみましょう。 ~~~

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
});/*
    看到API中removeListener移除方法时,以为应该是这样
    但是结果^_^!!!!!*/ee.removeListener('some_events', function(){
    console.log('成功移除事件some_events监听!');        
});

console.log('第一轮');
ee.emit('some_events', 'Wilson', 'Zhong');

emitter.on を使用して some_events のリスナーを登録した後、emiiter.removeListener を使用して some_events のリスナーを削除しました。それをトリガーするためにemitter.emitを呼び出しましたが、最終的には想像どおりに進んでいないことがわかりました。なぜ?

emiiter.removeListener の 2 番目のパラメータがコールバック関数であることは当然のことですが、API を注意深く読む必要があります。 ! !

成功シーンを見てみましょう~~~

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();var listener = function(foo,bar)
{
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
}var listener2= function(foo,bar)
{
    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );
}var listener3= function(foo,bar)
{
    console.log("第3个监听事件,参数foo=" + foo + ",bar="+bar );
}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('some_events', listener3);/*
    EventEmitter.removeListener(event, listener)  移除指定事件的监听器
    注意:该监听器必须是注册过的
    PS:上一个例子之后以会失败,很大原因就是忽略了监听器,理所当然的认为传个事件名就OK了,所以就悲剧了!*/ee.removeListener('some_events', listener);

ee.removeListener('some_events', listener3);

ee.emit('some_events', 'Wilson', 'Zhong');

例の書き方を使って some_events に 3 つ追加しましたリッスンし、最初と 3 番目のリスナーを削除し、最後にemiter.emit を使用して some_events をトリガーします。出力内で、emiter.removeListener で削除された最初と 3 番目のリスナーが機能しなくなっていることを見つけるのは難しくありません。当然有害です。emitter.removeListener の 2 番目のパラメータは削除されるリスナーであり、削除が成功した後のコールバック関数ではないことがわかります...^_^!

#emitter。 RemoveAllListeners([event])

emitter.removeListener が使用されていますが、イベントには複数のリスナーが存在する可能性があります。すべてを削除する必要がある場合、それらを 1 つずつ削除するのは明らかに快適なアプローチではなく、次の規則に準拠していません。怠惰な性質!

emitter.removeAllListeners によってもたらされる利便性を体験してみましょう!

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();var listener = function(foo,bar)
{
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
}var listener2= function(foo,bar)
{
    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );
}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)
{
    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );
});/*
    EventEmitter.removeAllListeners([event])   移除(批定事件)所有监听器
    参数1:可选参数,event  字符串,事件名*/ee.removeAllListeners('some_events');

ee.emit('some_events', 'Wilson', 'Zhong');

ee.emit('other_events', 'Wilson', 'Zhong');

上記の実行結果を見ると、some_events 2 つのリスナーがあることがわかります。登録されていました; other_events に 1 つのリスナーが登録されていました; Emitter.removeAllListeners を呼び出し、some_events イベント名を渡しました;

最後に、emitter.on 関数を使用して 2 つのイベント (some_events と other_events) をトリガーし、最終的に 2 つのイベントがsome_events によって登録されたイベント リスナーは存在しませんが、other_events によって登録されたリスナーはまだ存在します;

これは、emitter.removeAllListeners がパラメーターとしてイベント名を渡すと、渡されたイベント名を持つすべてのリスナーが何もせずに削除されることを意味します。他のイベント監視に影響を与えます。

Emitter.removeAllListeners は、イベント名パラメータを渡さずに直接実行できます。
var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();var listener = function(foo,bar)
{
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
}var listener2= function(foo,bar)
{
    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );
}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)
{
    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );
});/*
    EventEmitter.removeAllListeners([event])   移除(批定事件)所有监听器
    参数1:可选参数,event  字符串,事件名*/ee.removeAllListeners();

ee.emit('some_events', 'Wilson', 'Zhong');

ee.emit('other_events', 'Wilson', 'Zhong');

示例代码和传入参数时几乎一样,只是在调用emitter.removeAllListeners并没有传入指定事件名;

运行结果会发现some_events和other_events所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)

emitter.listeners(event)

 

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();var listener = function(foo,bar)
{
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );
}var listener2= function(foo,bar)
{
    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );
}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)
{
    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );
});/*
    EventEmitter.listeners(event)   //返回指定事件的监听数组
    参数1:event  字符串,事件名    
*/var listenerEventsArr = ee.listeners('some_events');

console.log(listenerEventsArr.length)for (var i = listenerEventsArr.length - 1; i >= 0; i--) {
    console.log(listenerEventsArr[i]); 
};

给some_events注册两个监听,调用emitter.listeners函数,传入some_events事件名,接收函数返回值;

从结果可以看出,返回值接收到some_events所有注册监听的集合!

emitter.setMaxListeners(n)

 一个事件可以添加多个监听是没错,但Nodejs默认最大值是多少呢?

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();/*
     给EventEmitter 添加11个监听*/for (var i = 10; i >= 0; i--) {
    ee.on('some_events',function()
    {
        console.log('第'+ (i +1) +'个监听');
    });
};

添加N个监听示例源码

上面示例中我用个循环给some_events添加11个监听,执行代码,发现warning信息出现,并且提示的比较详细了,需要用emitter.setMaxListeners()去提升限值

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();/*
    EventEmitter.setMaxListeners (n)   给EventEmitter设置最大监听
    参数1: n 数字类型,最大监听数
    
    超过10个监听时,不设置EventEmitter的最大监听数会提示:
    (node) warning: possible EventEmitter memory leak detected. 11 listeners added.
     Use emitter.setMaxListeners() to increase limit.
    设计者认为侦听器太多,可能导致内存泄漏,所以存在这样一个警告*/ee.setMaxListeners(15);/*
     给EventEmitter 添加11个监听*/for (var i = 10; i >= 0; i--) {
    ee.on('some_events',function()
    {
        console.log('第'+ (i +1) +'个监听');
    });
};

当我调用emitter.setMaxListeners传入15时,执行代码,warning信息不再出现;

emitter.setMaxListeners的作用是给EventEmitter设置最大监听数,感觉一般是不需要设置这个值,10个还不够用的情况应该是比较少了!

设计者认为侦听器太多会导致内存泄漏,所有就给出了一个警告!

其它...

 用的比较少的就不详细说了

EventEmitter.defaultMaxListeners

EventEmitter.defaultMaxListeners功能与setMaxListeners类似,
给所有EventEmitter设置最大监听
setMaxListeners优先级大于defaultMaxListeners

EventEmitter.listenerCount(emitter, event)

返回指定事件的监听数

 特殊的事件Error

引用自Node.js开发指南:EventEmitter 定义了一个特殊的事件 error,它包含了“错误”的语义,我们在遇到 异常的时候通常会发射 error 事件。当 error 被发射时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。我们一般要为会发射 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。

事件的继承

以后归到util里再讲一下吧,有兴趣的可以自已看看 http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor

【推荐学习:《nodejs 教程》】

以上がどのオブジェクトがnodejsのイベントモジュールによって提供されるかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。