search
HomeWeb Front-endJS TutorialIntroduction to the use of timer functions in js (with code)

This article brings you an introduction to the use of timer functions in js (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

1. setTimeout()

The setTimeout function is used to specify the number of milliseconds after which a function or a certain piece of code will be executed. It returns an integer representing the timer number, which can be used to cancel the timer later.

var timerId = setTimeout(func|code, delay)

In the above code, the setTimeout function accepts two parameters. The first parameter func|code is the name of the function or a piece of code to be delayed, and the second parameter delay is the number of milliseconds to delay execution.

It should be noted that the code to postpone execution must be put into setTimeout in the form of a string, because the engine uses the eval function internally to convert the string into code. If the postponed execution is a function, you can directly put the function name into setTimeout. On the one hand, the eval function has security concerns, and on the other hand, in order to facilitate the JavaScript engine to optimize the code, the setTimeout method usually takes the form of a function name, as shown below.

function f(){ 
 console.log(2);
}
setTimeout(f,1000);
// 或者
setTimeout(function (){
console.log(2)
},1000);

If the second parameter of setTimeout is omitted, this parameter defaults to 0.

In addition to the first two parameters, setTimeout also allows adding more parameters. They will be passed into the deferred function (callback function).

setTimeout(function(a,b){  
console.log(a+b);
},1000,1,1);

In the above code, setTimeout has a total of 4 parameters. The last two parameters will be used as parameters of the callback function when the callback function is executed after 1000 milliseconds.

IE9.0 and below only allow setTimeout to have two parameters and do not support more parameters. There are three solutions at this time. The first is to run the callback function with parameters in an anonymous function, and then enter the anonymous function into setTimeout.

setTimeout(function() {
  myFunc("one","two", "three");
}, 1000);

In the above code, myFunc is the function that really wants to defer execution and has three parameters. If you put setTimeout directly, lower versions of IE cannot take parameters, so you can put it in an anonymous function.

The second solution is to use the bind method to bind the extra parameters to the callback function and generate a new function input setTimeout.

setTimeout(function(arg1){}.bind(undefined, 10), 1000);

In the above code, the first parameter of the bind method is undefined, which means that this of the original function is bound to the global scope, and the second parameter is the parameter to be passed into the original function. When run, it returns a new function that takes no parameters.

The third solution is to customize setTimeout and use the apply method to input parameters into the callback function.

<!--[if lte IE 9]>
<script>(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){
return function(c,t){
var a=[].slice.call(arguments,2);
returnf(function(){
c.apply(this,a)},t)}});
</script>
<![endif]-->

In addition to parameter issues, there is another thing to note about setTimeout: if the callback function delayed by setTimeout is a method of an object, then the this keyword in the method will point to the global environment instead of The object in which it was defined.

var x = 1;
var o = { 
 x: 2,  y: function(){
    console.log(this.x);
  }
};
setTimeout(o.y,1000);

Output result: 1

The above code outputs 1, not 2, which means that this of o.y no longer points to o, but to the global environment.

Look at another example where errors are not easy to find.

function User(login) {
  this.login = login;
  this.sayHi = function(){
    console.log(this.login);
  }
}
var user = new User(&#39;John&#39;);
setTimeout(user.sayHi, 1000);

The above code will only display undefined, because when user.sayHi is executed, it is executed in the global object, so this.login cannot get the value.

In order to prevent this problem, one solution is to execute user.sayHi in a function.

setTimeout(function() {
  user.sayHi();
}, 1000);

In the above code, sayHi is executed in the user scope, not in the global scope, so the correct value can be displayed.

Another solution is to use the bind method to bind sayHi to user.

setTimeout(user.sayHi.bind(user), 1000);

The HTML 5 standard stipulates that the minimum time interval for setTimeout is 4 milliseconds. In order to save power, the browser will expand the time interval to 1000 milliseconds for pages that are not in the current window. In addition, if the laptop is on battery power, Chrome and IE 9 and above will switch the time interval to the system timer, which is approximately 15.6 milliseconds.

2, setInterval()

The usage of the setInterval function is exactly the same as setTimeout. The only difference is that setInterval specifies that a task should be executed every once in a while, which means it is not an unlimited number of scheduled executions. .

<input type="button" onclick="clearInterval(timer)"value="stop">
<script>
  var i = 1  
var timer = setInterval(function(){
    console.log(2);
  }, 1000);
</script>

The above code means that a 2 will be output every 1000 milliseconds until the user clicks the stop button.

Like setTimeout, in addition to the first two parameters, the setInterval method can also accept more parameters, which will be passed into the callback function. Here is an example.

function f(){
  for (var i=0;i<arguments.length;i++){
    console.log(arguments[i]);
  }
}
setInterval(f, 1000, "Hello World");

If the web page is not in the current window (or tab) of the browser, many browsers limit the recurring tasks specified by setInteral to be executed at most once per second.

The following is an example of implementing web page animation through the setInterval method.

var p = document.getElementById(&#39;somep&#39;);
var opacity = 1;
var fader = setInterval(function() 
{  opacity -= 0.1;
  if (opacity >= 0) {
    p.style.opacity = opacity;
  } else {
    clearInterval(fader);
  }}, 100);

The above code sets the transparency of the p element every 100 milliseconds until it is completely transparent.

A common use of setInterval is to implement polling. The following is an example of polling whether the hash value of the URL has changed.

var hash = window.location.hash;
var hashWatcher = setInterval(function() {
  if (window.location.hash != hash) {
    updatePage(); 
 }}, 1000);

setInterval specifies the interval between "start execution" and does not consider the time consumed by each task execution itself. So in reality, the interval between executions will be less than the specified time. For example, setInterval specifies execution every 100ms, and each execution takes 5ms. Then the second execution will start 95 milliseconds after the first execution ends. If an execution takes a particularly long time, say 105 milliseconds, then after it ends, the next execution will start immediately.

为了确保两次执行之间有固定的间隔,可以不用setInterval,而是每次执行结束后,使用setTimeout指定下一次执行的具体时间。

var i = 1;
var timer = setTimeout(function() {
  alert(i++);
  timer = setTimeout(arguments.callee,2000);
}, 2000);

上面代码可以确保,下一个对话框总是在关闭上一个对话框之后2000毫秒弹出。

根据这种思路,可以自己部署一个函数,实现间隔时间确定的setInterval的效果。

function interval(func, wait){
  var interv = function(){
    func.call(null);
    setTimeout(interv,wait);
  };
  setTimeout(interv,wait);
}interval(function(){
  console.log(2);
},1000);

上面代码部署了一个interval函数,用循环调用setTimeout模拟了setInterval。

HTML5标准规定,setInterval的最短间隔时间是10毫秒,也就是说,小于10毫秒的时间间隔会被调整到10毫秒。

3,clearTimeOut(),clearInterval()

setTimeout和setInterval函数,都返回一个表示计数器编号的整数值,将该整数传入clearTimeout和clearInterval函数,就可以取消对应的定时器。

var id1 = setTimeout(f,1000);
var id2 = setInterval(f,1000);
clearTimeout(id1);
clearInterval(id2);

setTimeout和setInterval返回的整数值是连续的,也就是说,第二个setTimeout方法返回的整数值,将比第一个的整数值大1。利用这一点,可以写一个函数,取消当前所有的setTimeout。

(function() {
  var gid = setInterval(clearAllTimeouts,0);
  function clearAllTimeouts(){
    var id = setTimeout(function(){}, 0);
    while (id >0) {
      if (id !==gid) {
        clearTimeout(id);
      }
      id--;
    }
  }})();

运行上面代码后,实际上再设置任何setTimeout都无效了。

下面是一个clearTimeout实际应用的例子。有些网站会实时将用户在文本框的输入,通过Ajax方法传回服务器,jQuery的写法如下。

$(&#39;textarea&#39;).on(&#39;keydown&#39;, ajaxAction);

这样写有一个很大的缺点,就是如果用户连续击键,就会连续触发keydown事件,造成大量的Ajax通信。这是不必要的,而且很可能会发生性能问题。正确的做法应该是,设置一个门槛值,表示两次Ajax通信的最小间隔时间。如果在设定的时间内,发生新的keydown事件,则不触发Ajax通信,并且重新开始计时。如果过了指定时间,没有发生新的keydown事件,将进行Ajax通信将数据发送出去。

这种做法叫做debounce(防抖动)方法,用来返回一个新函数。只有当两次触发之间的时间间隔大于事先设定的值,这个新函数才会运行实际的任务。假定两次Ajax通信的间隔不小于2500毫秒,上面的代码可以改写成下面这样。

$(&#39;textarea&#39;).on(&#39;keydown&#39;, debounce(ajaxAction, 2500))

利用setTimeout和clearTimeout,可以实现debounce方法,该方法用于防止某个函数在短时间内被密集调用。具体来说,debounce方法返回一个新版的该函数,这个新版函数调用后,只有在指定时间内没有新的调用,才会执行,否则就重新计时。

function debounce(fn, delay){
  var timer = null;// 声明计时器
  return function(){
    var context =this;
    var args = arguments;
    clearTimeout(timer); 
   timer = setTimeout(function(){
      fn.apply(context,args); 
   }, delay);
  };
}

// 用法示例

var todoChanges = _.debounce(batchLog, 1000);
Object.observe(models.todo, todoChanges);

现实中,最好不要设置太多个setTimeout和setInterval,它们耗费CPU。比较理想的做法是,将要推迟执行的代码都放在一个函数里,然后只对这个函数使用setTimeout或setInterval。

4,运行机制

setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮EventLoop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。

这意味着,setTimeout和setInterval指定的代码,必须等到本轮EventLoop的所有同步任务都执行完,再等到本轮EventLoop的“任务队列”的所有任务执行完,才会开始执行。由于前面的任务到底需要多少时间执行完,是不确定的,所以没有办法保证,setTimeout和setInterval指定的任务,一定会按照预定时间执行。

setTimeout(someTask, 100);
veryLongTask();

上面代码的setTimeout,指定100毫秒以后运行一个任务。但是,如果后面的veryLongTask函数(同步任务)运行时间非常长,过了100毫秒还无法结束,那么被推迟运行的someTask就只有等着,等到veryLongTask运行结束,才轮到它执行。

这一点对于setInterval影响尤其大。

setInterval(function () {
  console.log(2);
}, 1000);
(function () {
  sleeping(3000);
})();

上面的第一行语句要求每隔1000毫秒,就输出一个2。但是,第二行语句需要3000毫秒才能完成,请问会发生什么结果?

结果就是等到第二行语句运行完成以后,立刻连续输出三个2,然后开始每隔1000毫秒,输出一个2。也就是说,setIntervel具有累积效应,如果某个操作特别耗时,超过了setInterval的时间间隔,排在后面的操作会被累积起来,然后在很短的时间内连续触发,这可能或造成性能问题(比如集中发出Ajax请求)。

5, setTimeout(f,0)

setTimeout的作用是将代码推迟到指定时间执行,如果指定时间为0,即setTimeout(f, 0),那么会立刻执行吗?

答案是不会。因为上一段说过,必须要等到当前脚本的同步任务和“任务队列”中已有的事件,全部处理完以后,才会执行setTimeout指定的任务。也就是说,setTimeout的真正作用是,在“消息队列”的现有消息的后面再添加一个消息,规定在指定时间执行某段代码。setTimeout添加的事件,会在下一次Event Loop执行。

setTimeout(f, 0)将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“消息队列”指定的任务)一结束就立刻执行。也就是说,setTimeout(f, 0)的作用是,尽可能早地执行指定的任务。而并不是会立刻就执行这个任务。

setTimeout(function () {
  console.log(&#39;hello world!&#39;);
}, 0);

上面代码的含义是,尽可能早地显示“hello world!”。

setTimeout(f, 0)指定的任务,最早也要到下一次EventLoop才会执行。请看下面的例子。

setTimeout(function() {
  console.log("Timeout");
}, 0)
function a(x) {
  console.log("a()开始运行");
  b(x);
  console.log("a()结束运行");
}
function b(y) {
  console.log("b()开始运行");
  console.log("传入的值为" + y);
  console.log("b()结束运行");
}
console.log("当前任务开始");
a(42);
console.log("当前任务结束");

输出结果如下:

// 当前任务开始, a() 开始运行, b() 开始运行, 传入的值为42,b() 结束运行, a() 结束运行, 当前任务结束

上面代码说明,setTimeout(f, 0)必须要等到当前脚本的所有同步任务结束后才会执行。

即使消息队列是空的,0毫秒实际上也是达不到的。根据HTML5标准,setTimeout推迟执行的时间,最少是4毫秒。如果小于这个值,会被自动增加到4。这是为了防止多个setTimeout(f, 0)语句连续执行,造成性能问题。

另一方面,浏览器内部使用32位带符号的整数,来储存推迟执行的时间。这意味着setTimeout最多只能推迟执行2147483647毫秒(24.8天),超过这个时间会发生溢出,导致回调函数将在当前任务队列结束后立即执行,即等同于setTimeout(f, 0)的效果。

6 ,正常任务与微任务

正常情况下,JavaScript的任务是同步执行的,即执行完前一个任务,然后执行后一个任务。只有遇到异步任务的情况下,执行顺序才会改变。

这时,需要区分两种任务:正常任务(task)与微任务(microtask)。它们的区别在于,“正常任务”在下一轮EventLoop执行,“微任务”在本轮Event Loop的所有任务结束后执行。

console.log(1);
setTimeout(function() {
  console.log(2);
}, 0);
Promise.resolve().then(function() {
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);

输出结果如下:

// 1, 5,3,4, 2

上面代码的执行结果说明,setTimeout(fn, 0)在Promise.resolve之后执行。

这是因为setTimeout语句指定的是“正常任务”,即不会在当前的Event Loop执行。而Promise会将它的回调函数,在状态改变后的那一轮Event Loop指定为微任务。所以,3和4输出在5之后、2之前。

正常任务包括以下情况。

•   setTimeout

•   setInterval

•   setImmediate

•   I/O

•   各种事件(比如鼠标单击事件)的回调函数

微任务目前主要是process.nextTick和 Promise 这两种情况。

相关推荐:


 

The above is the detailed content of Introduction to the use of timer functions in js (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
如何在 iPhone 相机上设置定时器如何在 iPhone 相机上设置定时器Apr 14, 2023 am 10:43 AM

您可以在 iPhone 相机上设置多长时间的定时器?当您在 iPhone 的相机应用程序中访问定时器选项时,您将获得在两种模式之间进行选择的选项:3 秒 (3s)和10 秒 (10s)。当您手持 iPhone 时,您可以使用第一个选项从前置或后置摄像头快速自拍。第二个选项在场景中很有用,可以在远处将 iPhone 安装到三脚架上来点击合影或自拍。 如何在 iPhone 相机上设置定时器 虽然在 iPhone 相机上设置定时器是一个相当简单的过程,但具体操作方式因所使用的 iPhone 机型而异。

如何实现Workerman文档中的定时器功能如何实现Workerman文档中的定时器功能Nov 08, 2023 pm 05:06 PM

如何实现Workerman文档中的定时器功能Workerman是一款强大的PHP异步网络通信框架,它提供了丰富的功能,其中就包括定时器功能。使用定时器可以在指定的时间间隔内执行代码,非常适合定时任务、轮询等应用场景。接下来,我将详细介绍如何在Workerman中实现定时器功能,并提供具体的代码示例。第一步:安装Workerman首先,我们需要安装Worker

如何在Java中设置每日定时任务执行的定时器?如何在Java中设置每日定时任务执行的定时器?Dec 27, 2023 am 11:10 AM

Java定时器:如何设置每天定时执行任务?在日常的Java开发中,我们经常会遇到需要每天定时执行某个任务的需求。比如说每天凌晨1点执行数据备份任务,或者每天晚上8点发送日报邮件等等。那么在Java中,我们可以使用定时器来实现这样的功能。Java提供了多种定时器的实现方式,本文将介绍基于Timer和ScheduledExecutorService两种方式来设置

java定时器表达式是什么java定时器表达式是什么Dec 27, 2023 pm 05:06 PM

定时器的表达式用于定义任务的执行计划。定时器的表达式是基于“在给定的时间间隔之后执行任务”的模型。表达式通常由两个部分组成:一个初始延迟和一个时间间隔。

定时器的工作原理是什么定时器的工作原理是什么Aug 16, 2023 pm 02:18 PM

定时器的工作原理可以分为硬件定时器和软件定时器两种类型。硬件定时器的工作原理是时钟信号源提供稳定的时钟信号作为计时器的基准。计数器从预设值开始计数,每当时钟信号到达时计数器递增。当计数器达到预设值时,定时器会触发一个中断信号通知中断控制器处理相应的中断服务程序。在中断服务程序中,可以执行一些预定的操作。软件定时器的工作原理是通过编程语言或系统提供的库函数或系统调用来实现的等等。

掌握Go语言文档中的time.NewTimer函数实现单次定时器掌握Go语言文档中的time.NewTimer函数实现单次定时器Nov 03, 2023 pm 02:19 PM

掌握Go语言文档中的time.NewTimer函数实现单次定时器,并附上具体代码示例。时间作为我们生活的基准,定时器是编程中非常常用的工具之一。在Go语言中,我们可以使用time包来处理时间相关的操作,其中NewTimer函数可以用于创建一个单次定时器。本文将介绍如何使用NewTimer函数来实现一个简单的单次定时器,并附上具体代码示例。在Go语言中,tim

如何在Java中设置定时执行每月任务?如何在Java中设置定时执行每月任务?Jan 11, 2024 pm 04:50 PM

Java定时器:如何设置每月定时执行任务?引言:在开发中,经常会遇到需要每月定时执行任务的场景,例如每月更新统计数据、定期发送报表等。Java提供了多种定时器实现方式,本文将介绍如何使用Java定时器来实现每月定时执行任务,并提供具体的代码示例。一、使用Timer类实现每月定时执行任务Timer类是Java提供的最基础的定时器类,通过它可以实现简单的定时任务

Phalcon中间件:为应用程序添加定时任务和定时器的功能Phalcon中间件:为应用程序添加定时任务和定时器的功能Jul 30, 2023 pm 06:08 PM

Phalcon中间件:为应用程序添加定时任务和定时器的功能引言:在开发Web应用程序时,我们经常会遇到需要定时执行某些任务或者在特定时间间隔内执行某个功能的需求。Phalcon作为一个高性能的PHP框架,提供了一种灵活的方式来实现这些功能,那就是通过中间件来添加定时任务和定时器。一、Phalcon中间件简介Phalcon中间件是一个在处理HTTP请求过程中可

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools