首页 > 语言 > JavaScript > 正文

详解Nodejs的timers模块

2024-05-06 15:04:21
字体:
来源:转载
供稿:网友

本模块,属于来模拟一些浏览器自带方法的模块,比如setTimeout,clearTimeout等方法,之所以会有该模块,在我看来,也是为了能让前端工程师使用起来,更简单,使用一个单独的模块,来把浏览器上的功能来模拟出来,那么就可以直接减少学习的成本,这样就可以花更少的时间,学习到更多的东西。

timers模块中,使用的C++的方法

timers模块中,调用了C++实现的方法,这些方法,在该模块中,占据了很重要的位置,所以,这里我们先来看下,在C++的方法中,提供了哪些方法。

var Timer = process.binding('timer_wrap').Timer; console.log(Timer); 

运行之后,在控制台,就会打印出如下的内容,它的格式如下

{  [Function: Timer]  // Timer构造函数,可以进行实例化  kOnTimeout: 0,  // 静态属性,公用,更改会影响其他的调用  now: [Function: now]  // 静态方法,获取类似时间戳的一个数字 } 

其中,Timer本身是一个构造函数,而这个构造函数中,还包含了一个静态属性和一个静态方法,关于静态属性和方法,基本上,这两个只是拿来使用的,是禁止修改的,并且,其使用方法比较简单,所以这里不多说了。
Timer既然还是一个构造函数,那么久是可以被实例化的,接下来,看下实例化之后的对象:

var Timer = process.binding('timer_wrap').Timer,  timer = new Timer(),  i = "";  console.log("obj has attribute:"); console.log(timer);  console.log("prototype method and attribute:"); for(i in timer){  console.log(i+"="+timer[i]); } 

把上面的代码,执行的结果如下:

obj has attribute: {}  prototype method and attribute: close=function close() { [native code] } ref=function ref() { [native code] } unref=function unref() { [native code] } start=function start() { [native code] } stop=function stop() { [native code] } setRepeat=function setRepeat() { [native code] } getRepeat=function getRepeat() { [native code] } again=function again() { [native code] } 

从上面的结果中可以看出,在Timer实例化之后,在对象本身,是没有属性和方法的,在原型链上,是有一些方法,至于这些方法,有什么用,就需要慢慢去看一下了。

timers模块中的一个基础--构造函数Timeout

之所以这里要把这个构造函数以单小节的形式给出,是因为在我看来,如果想要对整个timers模块中的逻辑有更好的认识,那么该模块的基础一个私有的构造函数的理解,还是很有必要的。

这里,我们首先来看一下源码:

var Timeout = function(after) {  // 定义内部属性,过时时间  this._idleTimeout = after;   // 循环链表中的两个属性,可以参考前篇文章linklist私有模块  this._idlePrev = this;  this._idleNext = this;   // 记录开始计时时间的属性  this._idleStart = null;   // 当时间到了,执行的回调函数  this._onTimeout = null;   // 该计时器,是否需要repeat,setInterval方法,该属性为true  this._repeat = false; };   function unrefdHandle() {  // unref方法的回调函数,内部this指向Timeout._handle属性  // 在该属性上,定义了owner属性,保存Timeout的实例化后的对象  this.owner._onTimeout();  if (!this.owner._repeat)   this.owner.close(); }  Timeout.prototype.unref = function() {  // 这个方法,是用来暂停计时器的  // 添加一个新的属性_handle用来对接C++提供的API接口  if (!this._handle) {   // 做一些初始的判断属性,设置初始值等   var now = Timer.now();   if (!this._idleStart) this._idleStart = now;   var delay = this._idleStart + this._idleTimeout - now;   if (delay < 0) delay = 0;    // 把this指向的计时器对象,清理掉,从计时器链表中清理掉   exports.unenroll(this);    // 介入C++提供的API方法   this._handle = new Timer();    // 添加一些属性,用来保存一些信息   this._handle.owner = this;   this._handle[kOnTimeout] = unrefdHandle;    // 开始计时,在delay后执行改方法的回调   this._handle.start(delay, 0);   this._handle.domain = this.domain;    // 调用C++提供的方法,停止计时器的执行   this._handle.unref();  } else {   // 如果之前有_handle属性,那么则直接停止   this._handle.unref();  } };  Timeout.prototype.ref = function() {  // 该方法,只有在unref之后,才起作用,恢复计时器的工作  // 如果在unref中,生成了_handle属性,那么使用该属性  // 调用C++提供的API,ref,恢复计时器的运行  if (this._handle)   this._handle.ref(); };  Timeout.prototype.close = function() {  // 当要关闭计时器对象时,如果定义过接入C++饿API的方法时  // 直接使用C++的方法,关闭  // 否则,把该方法,清理出去  // 不让它再lists链表中,那么当计时器执行到时,也不会执行该计时器的回调函数  this._onTimeout = null;  if (this._handle) {   this._handle[kOnTimeout] = null;   // 调用C++中提供的close方法,见前面构造函数Timer的原型链方法中   this._handle.close();  } else {   exports.unenroll(this);  } };             
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选