从实现倒计时谈闭包

本文探讨了面试中关于闭包的一个常见问题——实现倒计时功能。文章指出,常见使用setTimeout在循环中输出尾数的代码无法实现倒计时,原因是setTimeout的计时机制。setTimeout在当前任务队列结束后才开始计时,导致始终输出循环的最终值。文章提供了两种解决方案,强调通过传入参数来缓存循环数据以正确实现倒计时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试中在谈论闭包的时候有让实现一个倒计时功能,当时满脑子都是那个setTimeout压入栈不断输出循环尾数的例子,最后也是没有用闭包实现倒计时

首先来看看那个在循环中不断重复输出的setTimeout代码片:

var countDown = function(){
  		for(var i=10;i>0;i--)
  		{
  			setTimeout(function(){console.log(i);},1000);
  		}
  }



输出效果:


当然这个是没有实现倒计时功能的,原因呢:

首先,和setTimeout设置的时间是没有关系的,很多人怀疑是时间设置的问题,不信可以将时间设置为0,结果是一样的,这里就不演示了

当然,得分析分析setTimeout的循环机制:setTimeout是从队列结束的时候开始计时的,如果前面有进程没有结束,那么它就等到它结束再开始计时,在这里呢,任务队列就是它自己所在的循环。循环结束setTimeout才开始计时,所以无论如何,setTimeout里面的i都是最后一次循环的

解决方法呢如下:

 var countDown = function(){
  		for(var i=10;i>0;i--)
  		{
  			var a =function(v){
  				return function(){
  					console.log(v);
  				}
  			}
  			setTimeout(a(i),1000);
  		}
  }



因为setTimeout的第一个参数需要一个函数,所以返回一个函数给他,返回的同时把i作为参数传进去,通过形参v缓存了i,并带进返回的函数里面


当然了,这样写也是可以的:

var countDown = function(){
  		for(var i=10;i>0;i--)
  		{
  			var a =function(v){
  				
  					console.log(v);
  			
  			}
  			setTimeout(a(i),1000);
  		}
  }


总之呢:例子中遇到setTimeout的问题,原因就是回调等待循环队列结束造成的,解决的办法就是给回调函数传一个实参缓存循环的数据



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值