Node.js入门(二)
1、回调函数
回调函数举例,新建js文件callback.js
var mFun = function main(callback){
console.log('我是主函数,哈哈');
callback();
}
var helloFun = function callbackHello(){
console.log('我是回调函数 hello, 嘻嘻');
}
var worldFun = function callbackWorld(){
console.log('我是回调函数 World, 嘿嘿');
}
mFun(helloFun);
console.log("------------我是分割符---------------");
mFun(worldFun);
运行:node callback.js
输出:
我是主函数,哈哈
我是回调函数 hello, 嘻嘻
------------我是分割符---------------
我是主函数,哈哈
2、事件循环
2.1 无参数事件
// 加载事件模块。提个问题:node.js有多少模块呢?怎么查看
var event = require('events');
// 创建EventEmitter对象,类似于Qt中的信号和槽
var signal = new event.EventEmitter();
// 创建回调函数,类似与Qt中的槽函数
var soltFunc = function solt(){
console.log('我是信号-1');
console.log('-----------over------------');
console.log('谁是信号-2');
// 发射信号
signal.emit('signal-2');
}
// 连接事件和回调函数,类似于Qt中connect,将信号和槽连接起来
signal.on('signal-1', soltFunc);
signal.on('signal-2', function(){
console.log('我是信号-2');
console.log('-----------over------------');
})
console.log('谁是信号-1');
// 发射信号
signal.emit('signal-1')
打印输出
谁是信号-1
我是信号-1
-----------over------------
谁是信号-2
我是信号-2
-----------over------------
2.2 有参数事件
下面的代码除了演示,传递参数给事件回调函数,同时还演示一个事件触发两个监听器
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
3、函数作为参数的用法
3.1 “无参的函数”作为参数
function testFuncArg(func){
func();
}
function funcA(){
console.log("我是funcA");
}
testFuncArg(funcA);
testFuncArg(function(){console.log("我是没有名字的函数")});
打印输出:
我是funcA
我是没有名字的函数
3.2 “有参的函数”作为参数
function funcB(msg){
console.log("我是funcB,我说:", msg);
}
function testFuncArg2(func, arg){
func(arg);
}
testFuncArg2(funcB, "hello");
function testFuncArg3(func){
var msg = "world"
func(msg);
}
testFuncArg3(funcB);
function testFuncArg4(func){
func();
}
testFuncArg3(funcB("不能这样使用,因为会先执行funcB"));
4、EventEmitter详解
4.1 对象方法
例如上面用到的on和emit方法,EventEmitter常用方法如下:
- addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部。
- on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
- once(event, listener) 为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
- removeListener(event, listener) 移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。
- removeAllListeners([event]) 移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。
- setMaxListeners(n) 默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于改变监听器的默认限制的数量。
- listeners(event) 返回指定事件的监听器数组。
- emit(event, [arg1], [arg2], […]) 按监听器的顺序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false。
4.2 类方法
- listenerCount(emitter, event)返回指定事件的监听器数量。
4.3 事件
- newListener 该事件在添加新监听器时被触发。
- removeListener 从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。
4.4 error 事件
EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,在遇到 异常的时候通常会触发 error 事件。
当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。
因此一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:
var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit('error');
5、扩展:对象方法、类方法、原型方法
- 对象方法:实例化,即new后才能调用的方法;
- 类方法:不用实例化,就能调用,类似于C++的类静态函数;
- 原型方法:一般用于对象实例共享,在原型上面添加该方法,就能实现共享。这样就不用每一次初始化一个实例的时候,为其分配相应的内存了。
function People(name){
this.name=name;
//对象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//类方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
}
//测试
var p1=new People("Windking");
p1.Introduce(); //对象方法需要通过实例化对象去调用
People.Run(); //类方法不需要通过实例化对象去调用
p1.IntroduceChinese(); //原型方法也需要通过实例化对象去调用