events 模块是 node 中的基础模块,很多内置模块都继承于它,像 stream…
基本用法
1 | var events = require("events"); |
on(“event”,handler)
once(“event”,handler) 同 on,只接受一次
emit(“event”,arg1,arg2…)
add/remove/removeAll Listener 字面意思
setMaxListeners 设置最大 listener 的数量
listeners(event_name)函数返回 listener 数组,不提供 event name 的话,返回空数组
特殊事件newListener
1 | require("d:/js/start.js"); |
输出
1 | 新添加了监听器... |
没有手动调用 emit,却有事件触发了,及特殊之处,在调用 on/addListener/once 等添加 listener 的方法会触发 newListener 事件,尝试使用数组一条语句添加两个 listener,报错,listener must be a function
继承 EventEmitter 做法
有见到
1 | function Abc() { |
关于继承
当初看了语言精髓,不是精粹,绿皮国人写的,比较详细,以为都搞懂了,现在连 Object.create 都记不起来了,来理理总结下吧
- prototype
__proto__
,Object.getPrototype,Object.isPrototypeOf- Object.create
- util.inherits
- util._extend
首先__proto__
是对象的,prototype
是函数构造器的__proto__
= constructor.prototype
的,也就是
1 | function Abc() {} |
然后我将 Object.getPrototypeOf Object.isPrototype 和__proto__
写在一起,是因为底层就是__proto__
,而 node 已经可以使用__proto__
了
1 | abc.__proto__.isPrototypeOf(abc); //true |
Object.create(__proto__
,props);
指定__proto__
属性和其他的属性创建对象,这个 props 中可以写 value writable enumerable 等,下面 node 标准库的 util.inherits 会调用这个
util.inherits(subClass,baseClass)
两个构造器,继承,看源码
1 | exports.inherits = function(ctor, superCtor) { |
前面 Abc 继承 EventEmitter 类,abc = new Abc()
- Abc.super_ = EventEmitter
- Abc.prototype =
{__proto__
: EventEmitter.prototype , constructor : Abc }
这个 inherits 重置了一个构造器(Abc)的 prototype,导致在 inherits 调用之前的 Abc.prototype.self_method 被舍弃,为了取到 EventEmitter 构造器的部分,需要 EventEmitter.call(this),其实可以将 EventEmitter.prototype 改为 new EventEmitter(),只是这个构造函数不具备通用性,可能有其他参数.
1 | var util = require("util"); |
util._extend(origin,add)
源码
1 | exports._extend = function(origin, add) { |
简单看,就是合并 add 至 origin
我的实践__proto__
是很危险的,不要重置它,默认是指向 constructor.prototype 的
类继承用
- util.inherits,注意在内部调用基类构造函数,call(this),后面紧接着调用 util.inherits
- 手动指定 sub.prototype = new Base();当然 constructor 属性 = Base,可以重置回来
sub.prototype.constructor = sub;
Timer and Intervals
1 | var timeoutId = setTimeout(callback, time); |
不多介绍
ref() , unref()方法
在 C#的 Console Program 中为了停住看下结果,使用的是 Console.ReadLine(),按回车终止…,可是 node 的程序,只要有事件循环(event loop),timeout,interval 还没执行完的话,程序就不会退出,如果只有一个 timeout or interval 在运行的话,使用 id.unref()来使这个 timeout or interval 不执行了
1 | var id = setTimeout(function() { |
这样程序就不会等待五秒退出,而是立即退出…
ref()是 unref()的方向操作
process.nextTick 在下一个事件循环处执行回调
setImmediate/clearImmediate 立即事件