以构造函数和原型法重新实现定时器封装

本文详细介绍了如何使用JavaScript中的构造函数和原型方法实现定时器封装,包括构造函数的使用、构造函数改造出定时器以及原型方法优化定时器实现的过程。通过实例展示了如何创建具有不同回调函数和超时时间的定时器,以及如何使用这些定时器进行计时。

  上篇文章实现了“使用工厂模式和闭包实现定时器封装”,

http://www.cnblogs.com/lightsong/p/3703045.html

本文记录以构造函数和原型法对其重新实现。

 

  构造函数

  创建对象,包括定义 var obj = {}、 工厂创建、 和 构造函数。

工厂创建即在创建函数中, 定义对象, 并给对象赋属性和方法, 最后return出此对象。

构造函数,类似Java中类的构造函数, 函数中, 使用this.xxx 来定义属性和方法,此处的this表示实例化时候的对象,

实例化语句 var obj = new constructor(args)。

 

  构造函数改造出定时器

  直接上代码,即在所有的属性和方法前添加this., 实现的功能与工厂一致:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    </head>
    <body>
    <label>timer msg :</label> </br>
    <textarea id="timer_msg" style="width:500px; height:300px"></textarea>
    <script>
    $.fn.extend({printMsg : function(msg){
         var oldmsg = $(this).val();
         var newmsg = oldmsg + "\n" + msg;
         $(this).val(newmsg);
    }});
    
    var __nativeST__ = window.setTimeout;
    window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
      var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
      return __nativeST__(vCallback instanceof Function ? function () {
        vCallback.apply(oThis, aArgs);
      } : vCallback, nDelay);
    };
    
    function timer(fnAlarmIn, options)
    {
        /* external settable */
        this.timeout = 1000;
        this.fnAlarm = function(){
            $("#timer_msg").printMsg(this.timerHandle.toString() 
                + "-please add custom fnAlarm")
        };
        
        /* inner maintain variable */
        this.timerHandle;
        this.timerObj;
        
        /* set external variable */
        if ( fnAlarmIn )
        {
            this.fnAlarm = fnAlarmIn;
        }

        if ( options && options.timeout )
        {
            this.timeout = options.timeout;
        }
        
        this.start = function(){
            this.timerHandle = setTimeout.call(this, function(){
                $("#timer_msg").printMsg(this.getTimerID() + "-->timer triggered");
                this.fnAlarm.call(this);
                delete this.timerHandle;
            }, this.timeout);
            $("#timer_msg").printMsg(this.timerHandle.toString() + "-timer started");
        };
        
        this.stop = function(){
            $("#timer_msg").printMsg(this.timerHandle.toString() + "-timer stoped");
            clearTimeout(this.timerHandle)
            delete this.timerHandle;
        };
        
        this.getTimerID = function(){
            return this.timerHandle;
        };
    }

    var timer1 = new timer();
    timer1.start();
    timer1.stop();
    
    var timer2 = new timer(function(){
        $("#timer_msg").printMsg("timer custom alarm");
    }, {timeout:2000});
    timer2.start();
    
    var timer3 = new timer(function(){
        $("#timer_msg").printMsg(timer3.getTimerID()+"-timer custom alarm");
    }, {timeout:3000});
    timer3.start();
    
    var timer4 = new timer(function(){
        $("#timer_msg").printMsg(this.getTimerID()+"-timer custom alarm");
    }, {timeout:4000});
    timer4.start();
    </script>
    </body>
</html>

 

 

  构造函数中定义对象的方法, 为每个对象独有, 实际上此方法应该属于每个对象共有。

一来浪费内存,二来不符合对象行为抽象的逻辑。此问题就需要原型方法解决。

 

   原型方法

  原型 prototype,就是定义构造函数中,对象公共方法的手段, 

例如原型为 function constructor(){}; constructor.prototype.hello = function(){console.log("hello")}

则任何实例化的对象 var a = new constructor();  都可以调用 a.hello();

 

  原型方法优化构造函数实现的定时器

  直接上代码,功能与构造函数一致:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    </head>
    <body>
    <label>timer msg :</label> </br>
    <textarea id="timer_msg" style="width:500px; height:300px"></textarea>
    <script>
    $.fn.extend({printMsg : function(msg){
         var oldmsg = $(this).val();
         var newmsg = oldmsg + "\n" + msg;
         $(this).val(newmsg);
    }});
    
    var __nativeST__ = window.setTimeout;
    window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
      var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
      return __nativeST__(vCallback instanceof Function ? function () {
        vCallback.apply(oThis, aArgs);
      } : vCallback, nDelay);
    };
    
    function timer(fnAlarmIn, options)
    {
        /* external settable */
        this.timeout = 1000;
        this.fnAlarm = function(){
            $("#timer_msg").printMsg(this.timerHandle.toString() 
                + "-please add custom fnAlarm")
        };
        
        /* inner maintain variable */
        this.timerHandle;
        this.timerObj;
        
        /* set external variable */
        if ( fnAlarmIn )
        {
            this.fnAlarm = fnAlarmIn;
        }

        if ( options && options.timeout )
        {
            this.timeout = options.timeout;
        }
    }

    timer.prototype.start = function(){
        this.timerHandle = setTimeout.call(this, function(){
            $("#timer_msg").printMsg(this.getTimerID() + "-->timer triggered");
            this.fnAlarm.call(this);
            delete this.timerHandle;
        }, this.timeout);
        $("#timer_msg").printMsg(this.timerHandle.toString() + "-timer started");
    };
    
    timer.prototype.stop = function(){
        $("#timer_msg").printMsg(this.timerHandle.toString() + "-timer stoped");
        clearTimeout(this.timerHandle)
        delete this.timerHandle;
    };
    
    timer.prototype.getTimerID = function(){
        return this.timerHandle;
    };
    
    var timer1 = new timer();
    timer1.start();
    timer1.stop();
    
    var timer2 = new timer(function(){
        $("#timer_msg").printMsg("timer custom alarm");
    }, {timeout:2000});
    timer2.start();
    
    var timer3 = new timer(function(){
        $("#timer_msg").printMsg(timer3.getTimerID()+"-timer custom alarm");
    }, {timeout:3000});
    timer3.start();
    
    var timer4 = new timer(function(){
        $("#timer_msg").printMsg(this.getTimerID()+"-timer custom alarm");
    }, {timeout:4000});
    timer4.start();
    </script>
    </body>
</html>

 

 

 

 

 

 

转载于:https://www.cnblogs.com/lightsong/p/3724469.html

1.2.1 分析 协程从实现来说分为非对称协程对称协程以及有栈协程无栈协程,本文实现的是非对程有栈协程库,主要通过Linux环境提到的ucontext.h的函数簇来实现,里面提供了创建上下文,切换上下文的系统级api,切换自定义的对象,最底层就是通过切换上下文的系统级api来实现。当然简单的api封装对象,还需要用户手动切换协程,所以协程库中提供了协程调度器,主要用来消费协程。以上这些实现如果遇到阻塞IO的话,其实并没有什么效果,所以协程库通过epoll机制hook了某些IO函数来帮助提高其实用性,这样能够做到某个协程阻塞在IO时,能够让出执行权,并切换协程执行。 1.2.2 设计 主要包括几大模块。其一是日志模块,主要功能包括格式化输出日志流式输出日志,当然可以将日志输出到文件中,可以用来监视调试程序的运行情况;其二是配置模块,主要功能包括存储某些配置变量的名字数值,可以用来初始化某些类;其三是线程模块,主要功能包括简单线程的封装一些锁的实现,可以用来多线程的实现;其四是协程模块,主要功能便是封装系统环境api,提供协程对象实现,是后续几个模块的基础;其五是协程调度器模块,主要提供了一个N-M协程调度器,可以用来添加协程消费协程;其六是定时器模块,主要功能是添加定时任务消费定时任务;其七是IO调度器,这个模块基于协程调度器模块定时器模块epoll机制实现了IO事件协程对象的捆绑触发;最后是hook模块,主要功能是重新实现了某些IO函数,能够让某些阻塞的系统IO函数让出当前协程的执行权。 1.2.3 验证 通过本文提到的协程库epoll分别实现了两个测试程序,通过ab测试工具测试两个简易测试程序的rps值。 基于以上,写出研究方法、技术路线、实验手段、关键技术等的说
最新发布
04-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值