Node事件监听
1、将自定义事件添加到JavaScript对象
Emit(eventName,[args])函数触发eventName事件。
如果想直接把时间添加到自己的javascript对象:
1>.调用events.EventEmitter.call(this)来对象中继承EventEmitter功能
2>.把events.EventEmitter.prototype添加到对象的原型中
2、把事件监听器添加到对象
1> .addListener(eventName,callback):将回调函数附加到对象的监听器中。每当eventName事件被触发时,回调函数就被放置在事件队列中执行。
2> .on(eventName,callback):同上。
3> .once(eventName,callback):只有eventName事件第一次被触发时,回调函数才被放置在事件队列中执行。
事件监听器实例:
var http = require("http");
var events = require("events"); //引用events模块
http.createServer(function(request,response){
response.writeHead(200,{"Conetnt-Type":"text/html;charset = utf-8"});
if(request.url !== "/favicon.ico") //清除第二次访问
{
var account = new Account();
//把事件监听器添加到对象
account.addListener("balanceChanged",displayBalance);
account.addListener("balanceChanged",checkOverdraw);
account.addListener("balanceChanged",function()
{
checkGoal(this,1000);
});
account.deposit(220);
account.deposit(320);
account.deposit(600);
account.withdraw(1200);
response.end();
}
}).listen(8000);
console.log("start running......");
//自定义事件
function Account()
{
this.balance = 0;
//继承EventEmitter功能
events.EventEmitter.call(this);
//定义两个方法
this.deposit = function(amount)
{
this.balance += amount;
//触发balanceChanged事件
this.emit("balanceChanged");
};
this.withdraw = function (amount)
{
this.balance -= amount;
this.emit("balanceChanged");
};
}
//把events.EventEmitter.prototype添加到对象的原型中
Account.prototype.__proto__ = events.EventEmitter.prototype;
//显示余额
function displayBalance()
{
console.log("Account balance:$%d",this.balance);
}
//判断是否余额大于0
function checkOverdraw()
{
if(this.balance<0)
{
console.log("Account overdrawn!!!");
}
}
function checkGoal(acc,goal)
{
if(this.balance>goal)
{
console.log("Goal Achieved!");
}
}
<img src="https://img-blog.csdn.net/20160913233548556?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
回调函数
1、 向回调函数传递额外的参数:在一个匿名函数中实现该函数,再用来自匿名函数的参数调用回调函数
2、 在回调中实现闭包:某个回调函数需要访问父函数的作用域的变量,就需要提供闭包。
3、 使用一部函数时,如果两个函数都在事件队列上,则无法保证他们的运行顺序。
解决方案是:
让来自异步函数的回调再次调用该函数,指导没有更多的工作要做,以链式回调。
1. 匿名函数中实现参数
var http = require("http");
var events = require("events");
http.createServer(function(request,response){
response.writeHead(200,{"Conetnt-Type":"text/html;charset = utf-8"});
if(request.url !== "/favicon.ico")
{
var show = new CarShow();
show.on("sawCar",logCar);
//匿名函数中实现参数
show.on("sawCar",function(make){
var colors = ["red","blue","black"];
var color = colors[Math.floor(Math.random()*3)];
logColorCar(make,color);
});
show.seeCar("1");
show.seeCar("2");
show.seeCar("3");
show.seeCar("4");
show.seeCar("5");
show.seeCar("6");
response.end();
}
}).listen(8000);
console.log("start running......");
function CarShow() {
events.EventEmitter.call(this);
//匿名函数中实现参数
this.seeCar = function(make){
this.emit("sawCar",make);
};
}
CarShow.prototype.__proto__ = events.EventEmitter.prototype;
function logCar(make) {
console.log("Saw a "+make);
}
function logColorCar(make,color){
console.log("Saw a %s %s ",color,make);
}
<img src="https://img-blog.csdn.net/20160913233556275?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
2、 链式回调函数
var http = require("http");
var cars = ["Ferrari","Porsche","Bugatti","1","2"];
http.createServer(function(request,response){
response.writeHead(200,{"Content-Type":"text/html;charset = utf-8"});
if(request.url !== "/favicon.ico"){
//链式回调函数
logCars(cars);
response.end();
}
}).listen(8000);
console.log("start running......");
function logCar(car,callback) {
console.log("Saw a %s",car)
if(cars.length){
process.nextTick(function() {
callback();
});
}
}
function logCars(cars) {
var car = cars.pop();
logCar(car,function(){
logCars(cars);
});
}
<img src="https://img-blog.csdn.net/20160913233604540?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />