Node.js系列笔记-1(不定期更新)
- Node.js应用组成
- 引入required模块:用require指令载入Node.js模块
- 创建服务器:服务器用来监听请求
- 接收请求与响应请求:客户端使用浏览器或终端发送HTTP请求,服务器接收请求后返回相应数据
- 一些指令
- #npm install <Module Name>
- #npm -v //显示2.15.8
- #npm ls //显示当前下载的模块
- npm版本号
- X.Y.Z三位,分别代表主版本号、次版本号、补丁版本号
- 只修复bug,更新Z位
- 新增了功能且向下兼容,更新Y位
- 大变动,且向下不兼容,才更新X位
- Node.js REPL 交互式解释器
- Node.js REPL Read Eval Print Loop
- 表示一个电脑环境,类似于DOS终端或Unix shell
- 基本过程:读取-执行-打印-循环
- 使用变量
- 没有用var关键字的都会直接打印出来
- 使用var关键字的,可以使用console.log()来输出变量
- 使用下划线_获取上面表达式的结果,如var sum = _ 即获得上面的结果数
- Node.js回调函数
- 异步编程的直接体现
- 同步:发出功能调用时,未得到结果之前,该调用不返回,也就是会发生阻塞
- 异步:异步过程调用发出后,调用者不会立即得到结果,实际处理这个过程的部件完成后,通过状态、统治和回调来通知调用者
- 异步返回结果的三种途径:状态、通知和回调
- 状态:调用者需要每隔一段时间检查一次,效率低
- 通知:部件通知调用者,效率高
- 回调:通过回调函数,与通知没有本质区别
- 同步:synchronization
- 异步:asynchronization
- 回调函数在完成任务后会被调用,Node.js使用大量回调函数,Node.js所有API都支持回调函数
- 异步读文件的例子:
-
1 var fs = require("fs"); 2 fs.readFile('input.txt', function(err, data){ 3 if (err) return console.error(err); 4 cosole.log(data.toString()); 5 }); 6 cosole.log("exit!");
注意function实质上作为了readFile方法的一个参数了
-
- 异步编程的直接体现
- Node.js事件循环
- Node.js是单进程单线程应用程序,但是通过事件和回调支持并发
- Node.js每一个API都是一步的,作为一个独立线程运行,使用异步函数调用
- Node.js基本上所有事件机制都是用设计模式中的观察者模式实现
- Node.js单线程类似进入一个while(ture)的事件循环,知道没有事件观察者时退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数
- 事件驱动程序
- Node.js使用事件驱动模型,当WebServer接收请求后,关闭Server,引发回调函数,然后将处理完的请求放回处理队列,之后立刻去服务下一个请求
- 可扩展性强,因为WebServer一直接受请求而不等待任何读写操作(非阻塞式I/O或者事件驱动I/O)
- 生成一个主循环来监听事件,当检测到事件时触发回调函数
- 非常简洁
- 类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)
- Node应用程序如何工作?
- Node应用程序中,执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数
- Node.js EventEmitter
- Node.js所有的异步IO操作在完成时都会讲一个事件发送到事件队列
- 如一个net.Server对象会在每次有新连接时分发一个事件,一个fs.readStream对象会在文件被打开时发出一个事件
- 所有这些事件都是events.EventEmitter的一个实例
- EventEmitter类
- events模块只提供了一个对象,events.EventEmitter
- EventEmitter的核心就是事件触发与事件监听器功能的封装
- 引入events模块
- var events = require('events');
- 创建eventEmitter对象
- var eventEmitter = new events.EventEmitter();
- EventEmitter对象如果在实例化时发生错误,会触发'error'事件;当添加新的监视器时,‘newListener’事件会触发;当监听器被移除时,‘removeListener’事件被触发
- EventEmitter的每个事件由一个事件名和若干个参数组成,事件名是一个字符串
- 属性介绍
- 方法
- addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部
- on(event, listener) 为指定事件注册一个监听器,接受一个字符串event和一个回调函数
- once(event, listener) 为指定事件注册一个单次监听器,即监听器只会触发一次,触发后立即解除该监听器
- removeListener(event, listener) 移除监听器,且是注册过的监听器,这里匿名的监听器可能就没法移除了
- removeAllListeners(event) 移除改时间的所有监听器
- setMaxListeners(n) 默认情况下,EventEmitters如果你添加的监听器超过10个,会出警告信息,该函数用于提高监听器默认限制的数量
- listeners(event) 返回指定事件的监听器数组
- emit(event, [arg1], [arg2], ```) 按照参数顺序执行每个监听器只要事件有注册监听就返回true,否则返回false
- 类方法
- listenerCount(emitter, event) 返回指定事件的监听器数量
- 方法
- error事件
- EventEmitter定义了一个特殊的事件error,包含了错误的语义,遇到异常时会触发error事件
- 当error被触发时,EventEmitter规定如果没有响应的监听器,Node.js会把它当做异常,退出程序并输出错误信息
- 因此要为error事件设置监听器,避免遇到错误后整个程序崩溃
- 继承EventEmitter
- 大多数我们不会直接使用EventEmitter,而是在对象中继承它
- 包括fs、net、http在内的,只要是支持事件响应的核心模块都是EventEmitter的子类
- 原因:
- 首先,具有某个实体功能的对象实现事件符合语义,事件的监听和发射应该是一个对象的方法
- 其次,JavaScript是基于原型的,支持部分多重继承,继承EventEmitter不会打乱对象原有的继承关系
- Node.js所有的异步IO操作在完成时都会讲一个事件发送到事件队列