node mysql模型_Node.js的事件驱动模型

事件队列调度

Node可以通过传递回调函数将任务添加到事件队列中,这种异步的调度可以通过5种方式来实现这个目标:异步堵塞IO库(db处理、fs处理),Node内置的事件和事件监听器(http、server的一些预定义事件),开发者自定义的事件和监听器、定时器以及Node全局对象process的.nextTick()API。

3.1 异步堵塞IO库

其IO库提供的API有Node自带的Module(比如fs)和数据库驱动API,比如mongoose的.save(doc, callback)就是将繁重的数据库Insert操作以及回调函数交给子线程来操作,主线程只负责任务的调度。当MongoDB返回给Node操作结果后,回调函数才开始执行。

Dtree.create(frontData, function (err, dtree) {

if (err) {

console.log('Error: createDTree: DB failed to create due to ', err);

res.send({'success': false, 'err': err});

} else {

console.log('Info: createDTree: DB created successfully dtree = ', dtree);

res.send({'success': true, 'created_id': dtree._id.toHexString()});

}

});

比如这段处理Dtree存储的回调函数只有当事件队列中的接收到来自堵塞IO处理线程的执行完毕才会被执行。

3.2 Node内置的事件和事件监听器

Node原生的模块都预定义来一些事件,比如NET模块的一套服务状态事件。当Net中的Socket检测到close就会调用放置在事件循环中的回调函数,下例中就是将sockets数组中删除相应的socket连接对象。

socket.on('close', function(){

console.log('connection closed');

var index = sockets.indexOf(socket);

//服务器端断开相应连接

sockets.splice(index, 1);

});

3.3 开发者自定义的事件

Node自身和很多模块都支持开发者自定义事件和处理持戟处理函数,当然既然是自定义,那么触发事件也是显性地需要开发者。在Socket.io编程中就有很好的例子,开发者可以自定义消息事件来处理端对端的交互。

//socket监听自定义的事件消息

socket.on('chatMessage', function(message){

message.type = 'message';

message.created = Date.now();

message.username = socket.request.user.username;

console.log(message);

//同时也可以像对方发出事件消息

io.emit('chatMessage', message);

});

3.4 计时器(Timers)

Node使用前端一致的Timeout和Interval计时器,他们的区别在Timeout是延时执行,Interval是间隔一段事件执行。值得注意的是这组函数其实不属于JS语言标准,他们只是扩展。在浏览器中,他们属于BOM,即它的确切定义为:window.setTimeout和window.setInterval;与window.alert, window.open等函数处于同一层次。Node把这组函数放置于全局范围中。

除了这两个函数,Node还添加Immediate计时器,setImmediate()函数是没有事件参数的,在事件队列中的当前任务执行结束后执行,并且优先级比Timeout、Interbal高。

计时器的问题在于它在事件循环中并非精确的执行回调函数。《深入浅出Node.js》举了一个例子:当通过setTimeout()设定一个任务在10毫秒后执行,但是如果在9毫秒后,有一个任务占用了5毫秒的CPU,再次炖老定时器执行时,事件就已经过期了。

3.5 Node全局对象process的.nextTick()API

这个延时执行函数函数是在添加任务到队列的开头,下一次Tick周期开始时就执行,也就是在其他任务前调度。

nextTick的优先级是高于immediate的。并且每轮循环,nextTick中的回调函数全部都会执行完,而Immediate只会执行一个回调函数。这里有得说明每个Tick过程中,判断事件循环中是否有事件要处理的观察者。在Node的底层libuv,事件循环是一个典型的生产者/消费者模型。异步IO、网络请求是事件的生产者,回调函数是事件的消费者,而观察者则是在中间将传递过来的事件暂存起来。回调函数的idle观察者在每轮事件循环开始被检查,而check观察者后于idle观察者检查,两者之间被检查的就是IO操作的观察者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值