NodeJS学习历程(3)

来源:互联网 发布:提高淘宝店铺关注率 编辑:程序博客网 时间:2024/06/15 09:23

nodeJS使用事件、监听器、定时器和回调

 nodeJS通过其强大的事件驱动模型提供了可扩展性和性能,nodeJS应用程序在一个单线程事件驱动模型中运行。
    传统的线程网络模型,请求一个进入web服务器,分配一个线程,完成所有工作,直到请求完成并发出响应,在每一个线程上,函数以线性的方式,按顺序调用。
    Nodejs将工作添加到一个事件队列中,然后有一个单独的线程运行一个事件循环把这个工作提取出来,事件循环抓取事件队列中最上面的条目,执行它,然后抓取下一个条目。当执行长期运行或有IO阻塞的代码时,它不是直接调用该函数,而是把函数随同一个要在此函数完成后执行的回调一起添加到事件队列,当所有事件队列的都执行完毕后,nodeJS应用程序终止。
    阻塞IO的一些例子:
  • 读取文件
  • 查询数据库
  • 请求套接字
  • 访问远程服务

    工作原理:NodeJS事件模型中,工作作为一个带有回调的函数被添加到事件队列中,然后在事件循环线程中被提取出来。之后,在无阻塞的情况下,在事件循环线程上执行该函数;或在阻塞的情况下,在一个单独的线程上执行它。

    使用下列方法之一做出调用,如写入文件或连接到一个数据库。
  • 对阻塞IO调用之一做出调用,如写入文件或连接到一个数据库
  • 对内置的事件,如http.request或server.connection添加一个事件监听器
  • 创建自己的事件发射器并对它们添加自定义的监听器
  • 使用process.nextTick选项来调度在事件循环的下一次循环中被提取出的工作
  • 使用定时器来调度在特定时间数量或每隔一段时间后要做的工作。

1、实现定时:
setInterval()定时循环启动
setTimeout()延迟启动
setImmediate()立即执行
process.nextTick()此函数调度要在事件循环的下一次循环中运行的工作
2、实现监听、发射(EventEmitter)
       prefer: http://www.runoob.com/nodejs/nodejs-event.html
  • 事件使用一个EventEmitter对象发出,这个对象包含在events模块中,需require("events");
    • var events = require('events');
  • 使用call使对象继承EventEmitter
    • events.EventEmitter.call(MyObj)
  • 还需要把 events.EventEmitter.prototype添加到对象的原型中,
    • MyObj.prototype.__proto__=events.EventEmitter.prototype;
  • 然后就可以使用emit发出事件了
    • var myObj = new MyObj();
    • myObj.emit('someEvent');
  • 有了前面几步之后,就可以为事件添加监听器了,
    • ---给对象添加事件监听
      .addListener(eventName,callback):将回调函数附加到对象的监听器,每当eventName事件被触发时,回调函数就被放置在事件队列中执行。
      .on(eventName,callback),同上
      .once(eventName,callback)只有eventName事件第一次触发时,回调函数才被放置在事件队列中执行。
  • 也可以删除监听器
    • ---删除对象事件监听
      .listener(eventName):返回一个连接eventName事件的监听器函数的数组
      .setMaxListeners(n):如果多于n的监听器都加入到EventEmitter对象,就触发警报,默认值为10;
      .removeListener(eventName,callback):将callback函数从EventEmitter对象的eventName事件中删除
为了理解监听对象EventEmitter的使用,利用一个demo来演示。
<span style="white-space:pre"></span><pre name="code" class="javascript">/** * Created by Administrator on 2016/7/3. */var events = require('events');//创建一个对象function Account(){    this.balance=0;    //发射事件    events.EventEmitter.call(this);    this.desposit=function (amount) {        this.balance+=amount;        this.emit("balanceChanged");    };    this.withdraw = function (amount) {        this.balance-=amount;        this.emit("balanceChanged");    };}Account.prototype.__proto__ = events.EventEmitter.prototype;function displayBalance() {    console.log("Account balance: $%d",this.balance);}function checkOverDraw() {    if(this.balance<0){        console.log("Goal Achieved!!!");    }}function checkGoal(acc,goal) {    if(acc.balance>goal){        console.log("Goal Achieved");    }}var account = new Account();account.on("balanceChanged",displayBalance);account.on("balanceChanged",checkOverDraw);account.on("balanceChanged",function () {    checkGoal(this,1000);});account.desposit(220);account.desposit(320);account.desposit(600);account.withdraw(1200);




0 0
原创粉丝点击