nodejs入门总结二:事件驱动

JavaScript027

nodejs入门总结二:事件驱动,第1张

Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。

Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO)在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

events事件模块:

只有一个模块,EventEmitter核心就是事件触发emite,和事件监听on

应用

(1)const event=require("events")模块

(2)new一个新的对象new evnet.EventEmitter()

(3)on("eventName",function(error,data){})创建监听器,一个事件可以创建多个监听

(4)emit("eventName")触发事件

(5)addListener("eventName",function(error,data){})也可以监听事件

(6)listenerCount("eventName")获取监听器个数,

getMaxListeners()//获取监听器数量;

setMaxListeners(n)//设置监听器数量;

eventNames() 获取当前触发器实例注册的所有事件名

listeners(事件名称)获取指定事件下的所有监听器

rawListeners(事件名称) 获取指定事件下的所有监听器

(7)移除监听事件的监听器;removeListener("eventName",fun),removeAllListener()off(事件名称,监听器名称)

(8)once():只触发一次,被移除;

(9)prependListener(事件名称,监听器):优先触发,事件监听器;

(10)prependOnceListener(事件名称,监听器) 触发一次 触发后移除

(11)EventEmitter.defaultMaxListeners = 8 每一个触发器实例 同一个事件最多绑定10个监听器 超出报警告

触发器实例上的内部事件

(1)订阅就会触发 newListener

myEmitter.on('newListener',(eventName,listener)=>{

console.log( 新增事件${eventName} ,listener)

})

(2)移除监听器会触发 removeListener

myEmitter.on('removeListener',(eventName,listener)=>{

console.log( 移除事件${eventName} ,listener)

})

事件触发,放在调用堆栈中;定时器结束时,函数会被放入“消息队列”中

事件循环会赋予调用堆栈优先级,它首先处理在调用堆栈中找到的所有东西,一旦其中没有任何东西,便开始处理消息队列中的东西。

setTimeout、fetch、或其他的函数是使用的是消息队列:回调函数放在调用堆栈的末尾;

promise,async/await函数使用的是作业队列:前函数结束之前 resolve 的 Promise 会在当前函数之后被立即执行。

process.nextTick(fun):事件循环进行一次完整行程时我们成为一个滴答,传入的函数则指示引擎在当前操作结束(在下一个事件循环滴答开始之前)时调用此函数:

回掉函数的第一个参数是err,如果正确返回null

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型。

Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。

Node对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好。V8引擎执行Javascript的速度非常快,性能非常好。Node是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。

扩展资料:

Node采用一系列“非阻塞”库来支持事件循环的方式。本质上就是为文件系统、数据库之类的资源提供接口。向文件系统发送一个请求时,无需等待硬盘(寻址并检索文件),硬盘准备好的时候非阻塞接口会通知Node。

该模型以可扩展的方式简化了对慢资源的访问, 直观,易懂。尤其是对于熟悉onmouseover、onclick等DOM事件的用户,更有一种似曾相识的感觉。

Node.js 为单线程操作,所有的异步 I/O 操作在完成时都会发送一个事件到任务队列。

node的 events 模块中提供了 event.EventEmitter 对象,EventEmitter 的核心就是事件触发与事件监听器功能的封装。

EcentEmitter 对象的方法:

         addListener(event, listener) :  为指定事件添加一个监听器到监听器数组的尾部。

         on(event, listener) :  为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。

         emit(event, [arg1], [arg2], [...]) :  按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返false。

基本使用:

var EventEmitter = require('events').EventEmitter

var event = new EventEmitter()

event.on('mouse_out', function(){

        console.log('event 事件触发!')

})

setTimeout(function(){

    event.emit('mouse_out')

}, 1000)

执行: node event.js

结果:event 事件触发!

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。为什么要这样做呢?原因有两点:

首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。

其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。 

//定义监听事件

var listener = function(arg){

        console.log("listener:" + arg)

}

// 引入 events 模块

var EventEmitter = require('events').EventEmitter

//原型链实现继承

function client(){}

client.prototype.a=function(){

        console.log('aaaaaa')

}

client.prototype.__proto__ = EventEmitter.prototype

var client = new client()

client.a()

client.on('listener',listener)

client.emit('listener', "hello world")

//结果:

 a

listener:Hello World