1. Foreword
I have been using Nodejs for some time. Recently, I will review its API and use more new features in order to have a higher level of mastery. This summary of the API is different from the simple Chinese version of the English version. I will do more expansion and my own I hope it will be helpful to everyone, let’s start with the core Events
Nodejs’ Events implements an observer mode, which supports the core mechanism of Nodejs, and http/fs/mongoose, etc. all inherit Events and can add listening events. This design pattern is often used in client-side component programming ideas. Let’s briefly understand this pattern first.
The first time I came into contact with the observer pattern was in the Ext.util.observable source code of the Extjs framework. I was new to js at that time and felt that this pattern was very powerful. It was also the first design pattern I came into contact with. Later, it was also included in the underscore.js source code. Seeing that the latter is simpler and more elegant, I basically follow this idea when writing components.
The observer mode is to add a monitoring event to an object, such as on('show', callback), which will be triggered by the object when it meets the conditions such as show. The browser itself has implemented a monitoring mechanism for the dom.
If we add keyup monitoring for input, the purpose is to output its value
$( 'input' ).on( 'keyup', function(){ console.log( this.value ); } );
When you enter content in this way, its value will be output in the log.
But if we make a component such as Dialog, how can we monitor the most commonly used show/hide events?
The basic approach is to directly configure the callback during instantiation, such as
var dialog = new Dialog({ content: '这里是弹出框的内容', show: function(){ console.log( '当弹框时输出此段内容' ); } });
This can also be used, but it is obviously not flexible enough. How can I make the dialog like input and can add events at any time
2. Implementation of observer mode
First implement the Events object, which provides basic monitoring on and triggering emit. Events are stacked in the _events of the object in the form of 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 ); } ) } } }
Another abstract function is used to copy attributes for objects
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 ]; } } }
Implement a Dialog,
Implements creation only; method: show / hide; event: show / hide;
When you see the effect, add this style
.dialog{ position: fixed; top: 50%; left: 50%; margin: -50px 0 0 -100px; width: 200px; height: 120px; background: #fff; border: 5px solid #afafaf; }
Implement components
var Dialog = function( config ){ this.config = config; this.init( this.config ); };
Extended attributes
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 );
Generate an instance and add three show and hide listening events to it
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 ); } );
We added six different show events and hide events in six times.
When dialog.show() is executed, three corresponding logs will be output. The added events are saved in dialog._events, as shown in the figure
The three added shows are all output successfully, and the events are saved in the _events attribute
nodejs Events also implements this process.
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
The methods it provides include on, which is the abbreviation of addListener. They all add listening events to the instance. The other attributes are as their names suggest. Let’s briefly explain them
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 ); })
5. Application
To use Events, usually just instantiate it directly, as shown in the API section above
However, if we also implement a component on the nodejs side, such as the previous Dialog, how can we make Dialog also have the function of Events? Extend solution that can be implemented with Extjs
Create Dialog builder
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' );
In this way, the Events mechanism is implemented for a component. When the method is called, the event will be triggered
6. Summary
Nodejs provides a good monitoring mechanism and is also used in all its modules. It supports the most distinctive I/O mode of nodejs. For example, when we start the http service, it will monitor its connect / close, and when http.request Monitor data/end, etc. Understanding the monitoring mechanism is the basis for learning and understanding nodejs, and is also beneficial to improving programming ideas.

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version
Useful JavaScript development tools

Atom editor mac version download
The most popular open source editor

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software