Une brève discussion sur l'observateur Nodejs pattern_node.js
1. Avant-propos
J'utilise Nodejs depuis quelques temps. Récemment, je vais revoir son API et utiliser davantage de nouvelles fonctionnalités afin d'avoir un niveau de maîtrise plus élevé. Ce résumé de l'API est différent de la simple version chinoise de la version anglaise. . Je ferai plus d'expansion et la mienne, j'espère que cela sera utile à tout le monde, commençons par les événements principaux
.Les événements de Nodejs implémentent un mode observateur, qui prend en charge le mécanisme de base de Nodejs, et http/fs/mongoose, etc. héritent tous des événements et peuvent ajouter des événements d'écoute. Ce modèle de conception est souvent utilisé dans les idées de programmation de composants côté client. Commençons par comprendre brièvement ce modèle.
La première fois que je suis entré en contact avec le modèle d'observateur, c'était dans le code source Ext.util.observable du framework Extjs. J'étais nouveau sur js à cette époque et je sentais que ce modèle était aussi très puissant. premier modèle de conception avec lequel je suis entré en contact. Plus tard, il a également été inclus dans le code source de underscore.js. Étant donné que ce dernier est plus simple et plus élégant, je suis essentiellement cette idée lors de l'écriture des composants.
Le mode observateur consiste à ajouter un événement de surveillance à un objet, tel que on('show', callback), qui sera déclenché par l'objet lorsqu'il remplit les conditions telles que show Le navigateur lui-même a implémenté une surveillance. mécanisme pour le dom.
Si nous ajoutons une surveillance keyup pour l'entrée, le but est de sortir sa valeur
$( 'input' ).on( 'keyup', function(){ console.log( this.value ); } );
Lorsque vous saisissez du contenu de cette manière, sa valeur sera affichée dans le journal.
Mais si nous créons un composant tel que Dialog, comment pouvons-nous surveiller les événements afficher/masquer les plus couramment utilisés ?
L'approche de base consiste à configurer directement le rappel lors de l'instanciation, comme
var dialog = new Dialog({ content: '这里是弹出框的内容', show: function(){ console.log( '当弹框时输出此段内容' ); } });
Cela peut également être utilisé, mais ce n'est évidemment pas assez flexible. Comment puis-je faire en sorte que la boîte de dialogue ressemble à une entrée et ajouter des événements à tout moment
2. Mise en place du mode observateur
Implémentez d'abord l'objet Events, qui fournit une surveillance de base et le déclenchement de l'émission. Les événements sont empilés dans les _events de l'objet sous forme de json
.var Events = { on: function( name, callback){ this._events = this._events || {}; this._events[ name ] = this._events[ name ] || []; this._events[ name ].push( callback ); }, emit: function( name ){ this._events = this._events || {}; var args = Array.prototype.slice.call( arguments, 1 ), me = this; if( this._events[ name ] ){ $.each( this._events[ name ], function( k, v ){ v.call( me, args ); } ) } } }
Une autre fonction abstraite est utilisée pour copier les attributs des objets
function extend( source ){ var args = Array.prototype.slice.call( arguments, 1 ); for( var i = 0, parent; parent = args[i]; i++ ){ for( var prop in parent ){ source[ prop ] = parent[ prop ]; } } }
Mettre en œuvre un dialogue,
Implémente la création uniquement ; méthode : afficher / masquer ; événement : afficher / masquer <🎜 ;
.dialog{ position: fixed; top: 50%; left: 50%; margin: -50px 0 0 -100px; width: 200px; height: 120px; background: #fff; border: 5px solid #afafaf; }
var Dialog = function( config ){ this.config = config; this.init( this.config ); };
extend( Dialog.prototype, { init: function( config ){ this.render( config ) }, render: function( config ){ this.el = $( '<div>' ).addClass( 'dialog' ); this.el.html( config.content ); $( 'body' ).append( this.el ); }, show: function( param ){ this.el.fadeIn(); this.emit( 'show', param ); }, hide: function( param ){ this.el.fadeOut(); this.emit( 'hide', param ); } }, Events );
var dialog = window.dialog = new Dialog({ content: 'dialog one' }); dialog.on( 'show', function( txt ){ console.log( 'dialog show one ' + txt ); } ); //do something dialog.on( 'show', function( txt ){ console.log( 'dialog show two ' + txt ); } ); //do something dialog.on( 'show', function( txt ){ console.log( 'dialog show three ' + txt ); } ); //do something dialog.on( 'hide', function( txt ){ console.log( 'dialog hide one ' + txt ); } ); //do something dialog.on( 'hide', function( txt ){ console.log( 'dialog hide two ' + txt ); } ); //do something dialog.on( 'hide', function( txt ){ console.log( 'dialog hide three ' + txt ); } );
Lorsque dialog.show() est exécuté, trois journaux correspondants seront générés. Les événements ajoutés sont enregistrés dans dialog._events, comme le montre la figure
nodejs Events implémente également ce processus.
3. Structure
var Events = require( 'events' ); console.log( Events ); /* 输出如下数据,可以看出 Events指向其EventEmiter { [Function: EventEmitter] EventEmitter: [Circular], usingDomains: [Getter/Setter], defaultMaxListeners: 10, init: [Function], listenerCount: [Function] } */ var myEmitter = new Events(); console.log( myEmitter ); /* { domain: null, _events: {}, //可以看到实例本身也有_events属性,添加的监听的事件就保存在这里 _maxListeners: undefined} */ console.log( myEmitter.__proto__ ); /* { domain: undefined, _events: undefined, _maxListeners: undefined, setMaxListeners: [Function: setMaxListeners], emit: [Function: emit], addListener: [Function: addListener], on: [Function: addListener], once: [Function: once], removeListener: [Function: removeListener], removeAllListeners: [Function: removeAllListeners], listeners: [Function: listeners] } */ myEmitter.on( 'show', function( txt ){ console.log( 'one ' + txt )}) myEmitter.on( 'show', function( txt ){ console.log( 'tow ' + txt )}) myEmitter.on( 'hide', function( txt ){ console.log( 'one ' + txt )}) myEmitter.emit( 'show', 'show' ); myEmitter.setMaxListeners( 10 ); console.log( myEmitter ); /* { domain: null, _events: { show: [ [Function], [Function] ], hide: [Function] }, //添加后的事情,以json形式存放 _maxListeners: 10 } */
4.API
Les méthodes qu'il fournit incluent on, qui est l'abréviation de addListener. Elles ajoutent toutes des événements d'écoute à l'instance. Les autres attributs sont comme leurs noms le suggèrent.
property _events: undefined, //以压栈形式存放on进来的事件 _maxListeners: undefined //设置最大监听数,超出提warn ---------------------------------------------------------------------------------------------------------------- method setMaxListeners: [Function: setMaxListeners], /*设置私有属性_maxListeners的值,默认Events会在当某监听事件多于10个时发现警告(见上面Events.defaultMaxListeners),以防止内存泄露,如 (node) warning: possible EventEmitter memory leak detected. 11 show listeners added. Use emitter.setMaxListeners() to increase limit. 但这只是个友好的提醒,可以通过设置最大监听数来规避这个问题 myEmitter.setMaxListeners( 20 ); */ emit: [Function: emit], /*触发监听事件 emitter.emit( event, [arg1], [arg2], ... ) 如myEmitter.on( 'show', 'prompt content' ); 参数1为事件名,参数二供on回调里的参数 */ addListener: [Function: addListener], /* 添加监听事件 emitter.addListener( event, listener ); 如 myEmitter.addListener( 'show', function( txt ){ console.log( txt ) } ); 参数一是事件名,参数二是对应的回调,回调里的参数就是 emit里的arguments.prototype.slice.call(1); */ on: [Function: addListener], /* 是addListener简写 */ once: [Function: once], /* 作用同 on,不过emit一次后就失效了 emitter.once( event, listener ); 如 myEmitter.once( 'show', function( txt ){ console.log( txt ) } ); 当myEmitter.emit执行第二次时没有输出 */ removeListener: [Function: removeListener], /* 移除指定事件的指定回调,此时回调不能再用匿名函数。 emitter.removeListener( event, listener ); 如 function show( txt ){ console.log( txt ) }; myEmitter.on( 'show', show ); console.log( myEmitter._events ); // { show: [ Function: show ] } myEmitter.removeListener( 'show', show ); console.log( myEmitter._events ); // {} */ removeAllListeners: [Function: removeAllListeners], /* 删除指定事件的所有回调 emitter.removeAllListeners( [ event ] ); 如 myEmitter.removeAllListeners( 'show' ); //删除所有show监听 myEmitter.removeAllListeners(); //删除所有监听 */ listeners: [Function: listeners] /* 查看指定监听 emitter.listeners( event ); 如 myEmitter.listeners( 'show' ); //返回一个数组 同我们前面使用的 myEmitter._events[ 'show' ] */ 另外Events类本身提供了一个方法 Events.listenerCount( emitter, event ); 获取指定实例下指定监听数 如 Event.listenerCount( myEmitter, 'show' ) ----------------------------------------------------------------------------------------------- 还有两个event newListener / remoteListener,分别应用于为实例添加( on / once )和删除( removeListener ) 操作。 emitter.on( event, listener ); emitter.on( 'newListener', function( event, listener ){ console.log( emitter.listeners( 'show' ) ); //注意,此时监听还并没有添加到 emitter.listeners console.log( arguments ); }); emitter.on( 'removeListener', function(){ console.log( emitter.listeners( 'show' ) ); console.log( arguments ); })
Pour utiliser des événements, il suffit généralement de les instancier directement, comme indiqué dans la section API ci-dessus
Cependant, si nous implémentons également un composant côté nodejs, comme le Dialog précédent, comment pouvons-nous faire en sorte que Dialog ait également la fonction d'Événements ? Solution d'extension pouvant être implémentée avec Extjs
Créer un générateur de dialogue
var Dialog = function(){ //do something } //抽象apply函数,提供属性的深度复制,同上面的extend function apply( source ){ var args = Array.prototype.slice.call( arguments, 1 ); for( var i = 0, parent; parent = args[i]; i++ ){ for( var prop in parent ){ source[ prop ] = parent[ prop ]; } } } //抽象extend函数,用于实现继承 var extend = function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; var oc = Object.prototype.constructor; return function(sb, sp, overrides){ if(typeof sp == 'object'){ overrides = sp; sp = sb; sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; } var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; if(spp.constructor == oc){ spp.constructor=sp; } sb.override = function(o){ apply(sb, o); }; sbp.superclass = sbp.supr = (function(){ return spp; }); sbp.override = io; apply(sb, overrides); sb.extend = function(o){return extend(sb, o);}; return sb; }; }(); //将Events属性继承给Dialog Dialog = extend( Dialog, Events ); //为Dialog新增 method show,其内触发 event show Dialog.prototype.show = function( txt ){ this.emit( 'show', txt ); } var dialog = new Dialog(); //添加监听事件show dialog.on( 'show', function(txt){ console.log( txt )}); //执行method show时,就会触发其内定义的show events,输出 this is show dialog.show( 'this is show' );
6.Résumé
Nodejs fournit un bon mécanisme de surveillance et est également utilisé dans tous ses modules. Il prend en charge le mode d'E/S le plus distinctif de nodejs. Par exemple, lorsque nous démarrons le service http, il surveillera sa connexion/fermeture, et quand. http.request Surveiller les données/fin, etc. Comprendre le mécanisme de surveillance est la base de l'apprentissage et de la compréhension de nodejs, et est également bénéfique pour améliorer les idées de programmation.
Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...

Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...

JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.

Discussion approfondie des causes profondes de la différence de sortie Console.log. Cet article analysera les différences dans les résultats de sortie de la fonction Console.log dans un morceau de code et expliquera les raisons derrière. � ...

Une fois que vous avez maîtrisé le didacticiel TypeScript de niveau d'entrée, vous devriez être en mesure d'écrire votre propre code dans un IDE qui prend en charge TypeScript et de le compiler en JavaScript. Ce tutoriel plongera dans divers types de données dans TypeScript. JavaScript a sept types de données: null, non défini, booléen, numéro, chaîne, symbole (introduit par ES6) et objet. TypeScript définit plus de types sur cette base, et ce tutoriel les couvrira tous en détail. Type de données nuls Comme javascript, null en typeScript

La discussion sur la réalisation des effets de défilement de parallaxe et d'animation des éléments dans cet article explorera comment réaliser le site officiel de Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ...

JavaScript peut être exécuté dans PowerPoint et peut être implémenté en appelant des fichiers JavaScript externes ou en intégrant des fichiers HTML via VBA. 1. Pour utiliser VBA pour appeler les fichiers JavaScript, vous devez activer les macros et avoir des connaissances en programmation VBA. 2. ENCHED des fichiers HTML contenant JavaScript, qui sont simples et faciles à utiliser mais sont soumis à des restrictions de sécurité. Les avantages incluent les fonctions étendues et la flexibilité, tandis que les inconvénients impliquent la sécurité, la compatibilité et la complexité. En pratique, l'attention doit être accordée à la sécurité, à la compatibilité, aux performances et à l'expérience utilisateur.
