js闭包定时器+队列执行

写一个定时器用法的文章,此为以前帮同学做的一个笔试题,当时觉得有一定的难度,需求如下文,需要创建一个动画构造器。
接受三个参数yt(func,times,duration)
func:动画函数,
times:函数执行的次数,
duration:函数执行间隔,

构造器返回一个闭包 var closure = yt(func,times,duration);动画函数的参数在调用closure(params)时传入,这里面首先一个问题就是闭包是为了能够访问父函数域中的变量,而函数在作为参数传入setTimeout时,父函数域为window


所以这里要么用bind绑定需要的参数,像这样,setTimeout(arguments.callee.bind(this,a),duration);arguments.callee为当前正在运行的函数


要么传入一个匿名函数,像这样setTimeout(function(){},duration);函数的父作用域为该函数声明时的父作用域(而不是调用时的父作用域),这个小细节在开发中很重要,当然当前场景下这里面还有点问题,在此不做过多表述


于是可得到这样一个函数,运行后会每隔一面alert(“hello”)5次


function yt(func,times,duration){
var i = 1;        
return function(a,sambol){
            func(a+""+i);
            var timer=setTimeout(arguments.callee.bind(this,a),duration);
            ++i>times&&[clearTimeout(timer),timer=null,i=1];
        }
    }


但是,如果连续调用两次,yt0("hello");yt0(2);这个运行起来就会错乱,因为他们是公用的同一个闭包,这样同一时间会产生两个定时器在运行并且输出是先hello再2,交替输出,这肯定不是我们想要的,jQuery的原码在做动画时就是采用队列执行的形式,所以我这里也做一个队列,让前5次hello执行完再执行后5次2


方法是定义一个数组duilie=[],每人为调用一次yt0则将其参数添加到duilie=[],执行完一轮则将该参数踢出数组,并启动下一组动画,duilie的length为零时停止定时器
代码如下:


function yt(func,times,duration){
        var duilie = [];
        var i = 1;
        return function(a,sambol){
            if(sambol===undefined){//标识字段决定是认为调用还是定时器自动调用
                duilie.push(a);
                if(duilie.length !==1){//length不等于1时表示定时器不是首次启动,不需要启动第二个定时器
                    return ;
                }
            }
            if(duilie.length ===0){//length为零时退出定时器
                return ;
            }
            func(duilie[0]+" "+i);
            var timer=setTimeout(arguments.callee.bind(this,a,true),duration);//绑定标志参数true,表示是计时器调用的
            ++i>times&&[duilie.shift(),timer=null,i=1];//数组中可执行多句话
        }
    }
    var yt0=yt(alert,5,1000);
    yt0("hello");
    yt0(2);


笔者还打算写两篇文章:
1,面向对象的编程
2,利用逻辑悖论编写程序(程序能进行到某一步时必然经过了某些步骤,所以在当前环节有更多的属性可以使用)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值