如何使用定时器settimeout,setInterval执行能传递参数的函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用定时器settimeout,setInterval执行能传递参数的函数相关的知识,希望对你有一定的参考价值。

无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决。经网上查询后整理如下:\x0d\x0a例如对于函数hello(_name),它用于针对用户名显示欢\x0d\x0a迎信息:\x0d\x0avar userName="jack";\x0d\x0a//根据用户名显示欢迎信息\x0d\x0afunction hello(_name)\x0d\x0a alert("hello,"+_name);\x0d\x0a\x0d\x0a这时,如果企图使用以下语句来使hello函数延迟3秒执行是不可行的:\x0d\x0awindow.setTimeout(hello(userName),3000);\x0d\x0a这将使hello函数立即执行,并将返回值作为调用句柄传递给setTimeout函数,其结果并不是程序需要的。而使用字符串形式可以达到想要的结果:\x0d\x0awindow.setTimeout("hello(userName)",3000);这是方法(一)\x0d\x0a这里的字符串是一段javascript代码,其中的userName表示的是变量,而且经测试,这个变量要是个全局的,如果是在某函数里面如此调用 setTimeout,而此变量只是个函数内部变量的话,是会报变量不存在的。但这种写法不够直观,而且有些场合必须使用函数名,于是有人想到了如下\x0d\x0a方法(二):\x0d\x0a 参考技术A 无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,这就需要想方法解决。经网上查询后整理如下:
例如对于函数hello(_name),它用于针对用户名显示欢
迎信息:
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name)
alert("hello,"+_name);

这时,如果企图使用以下语句来使hello函数延迟3秒执行是不可行的:
window.setTimeout(hello(userName),3000);
这将使hello函数立即执行,并将返回值作为调用句柄传递给setTimeout函数,其结果并不是程序需要的。而使用字符串形式可以达到想要的结果:
window.setTimeout("hello(userName)",3000);这是方法(一)
这里的字符串是一段JavaScript代码,其中的userName表示的是变量,而且经测试,这个变量要是个全局的,如果是在某函数里面如此调用 setTimeout,而此变量只是个函数内部变量的话,是会报变量不存在的。但这种写法不够直观,而且有些场合必须使用函数名,于是有人想到了如下
方法(二):
<script language="JavaScript" type="text/javascript">
<!--
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name)
alert("hello,"+_name);

//创建一个函数,用于返回一个无参数函数
function _hello(_name)
return function()
hello(_name);


window.setTimeout(_hello(userName),3000);
//-->
</script>
这 里定义了一个函数_hello,用于接收一个参数,并返回一个不带参数的函数,在这个函数内部使用了外部函数的参数,从而对其调用,不需要使用参数。在 window.setTimeout函数中,使用_hello(userName)来返回一个不带参数的函数句柄,从而实现了参数传递的功能。
另外也有人通过修改settimeout、setInterval来实现,相比是比较理想的。即下面的
方法三:
<script language="JavaScript" type="text/javascript">
<!--
var userName="jack";
//根据用户名显示欢迎信息
function hello(_name)
alert("hello,"+_name);
//*=============================================================
//* 功能: 修改 window.setInterval ,使之可以传递参数和对象参数
//* 方法: setInterval (回调函数,时间,参数1,,参数n) 参数可为对象:如数组等
//*=============================================================
var __sto = setInterval;
window.setInterval = function(callback,timeout,param)
var args = Array.prototype.slice.call(arguments,2);
var _cb = function()
callback.apply(null,args);

__sto(_cb,timeout);

window.setInterval(hello,3000,userName);
//-->本回答被提问者采纳

如何实现setTimeout和setInterval

首先在针对浏览器端的默认实现中,setTimeout和setInterval的定时是不准确的,因为我们知道js是单线程的,如果前面的代码耗费了较长的时间,那么会导致后面的定时器不能按时执行。此外setInterval会带来性能上的问题,比如存在执行累积的问题等等。我们完全可以使用requestAnimationFrame来实现定时器的要求,首先 requestAnimationFrame 自带函数节流功能,基本可以保证在 16.6 毫秒内只执行一次
requestAnimationFrame的语法很简单:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。

// setTimeout的实现
function mySetTimeout(callback,timeout){
  let timer;
  let time = new Date();
  let endTime = timeout || 0
  const loop = ()=> {
    timer = window.requestAnimationFrame(loop);
    if(new Date() - time >= endTime) {
      callback.call(this,timer);
      window.cancelAnimationFrame(timer);
    }
  }
  window.requestAnimationFrame(loop);
}
mySetTimeout(()=> {
  console.log(\'hh\')
})
function mySetInterval(callback,interval){
  let timer;
  let startTime = new Date();
  const loop = ()=> {
    timer = window.requestAnimationFrame(loop);
    if(new Date() - startTime >= interval) {
      callback.call(this,timer);
      startTime = new Date();
    }
  }
  timer = window.requestAnimationFrame(loop);
  return timer;
}
var a = 1;
mySetInterval(timer=> {
  a++;
  if(a >= 5){
    window.cancelAnimationFrame(timer);
  }
  console.log(a,\'1秒一次\');
},1000)

以上是关于如何使用定时器settimeout,setInterval执行能传递参数的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用定时器settimeout,setInterval执行能传递参数的函数

如何使用定时器settimeout,setInterval执行能传递参数的函数

如何使用定时器settimeout,setInterval执行能传递参数的函数

如何使用定时器settimeout,setInterval执行能传递参数的函数

如何实现setTimeout和setInterval

为啥 requestAnimationFrame 比 setInterval 或 setTimeout 更好