Home Web Front-end JS Tutorial Things about setTimeout in JavaScript

Things about setTimeout in JavaScript

Dec 07, 2016 am 09:52 AM
javascript

1. Single-threading about setTimeout

For a long time, everyone has been saying that Javascript is single-threaded. No matter when the browser has only one thread running the JavaScript program.

However, I don’t know if you have any doubts - isn’t the setTimeout (similar to setInterval, Ajax) we use in the programming process executed asynchronously? ! !

For example:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <script>
   console.log("a");
   //利用setTimeout延迟执行匿名函数
   setTimeout(function(){
    console.log("b");
   },100);
   console.log("c");
  </script>
 </body>
</html>
Copy after login

Run the code and open the chrome debugger, and you will get the following results

Things about setTimeout in JavaScript

This result is easy to understand, because the content in my setTimeout is executed after 100ms, of course. First output a, then output c, and then output b in setTimeout after 100ms.

Hey, isn’t Javascript single-threaded? Can it be multi-threaded? ! !

Actually, no. setTimeout does not break the single-threaded mechanism of JavaScript, it is actually single-threaded.

Why do you say this? Then you have to understand what setTimeout is.

Please look at the code below and guess the result:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <script>
   var date = new Date();
   //打印才进入时的时间
   console.log(&#39;first time: &#39; + date.getTime());
   //一秒后打印setTimeout里匿名函数的时间
   setTimeout(function(){
    var date1 = new Date();
    console.log(&#39;second time: &#39; + date1.getTime() );
    console.log( date1.getTime() - date.getTime() );
   },1000);
   //重复操作
   for(var i=0; i < 10000 ; i++){
    console.log(1);
   }
  </script>
 </body>
</html>
Copy after login

Looking at the above code, guess what the output result is? 1000 milliseconds?

We open the chrome debugger, see the picture below

Things about setTimeout in JavaScript

Nani, why is it not 1000 milliseconds? ! ! !

Let’s take a look at the following code again:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <script>
   //一秒后执行setTimeout里的匿名函数,alert下
   setTimeout(function(){
    alert("monkey");
   },1000);
   while(true){};
  </script>
 </body>
</html>
Copy after login

After running the code!

Why do I keep refreshing, the browser is stuck, and there is no alert! !

Logically, even if I loop infinitely while, I still have to alert after 1 second.

All kinds of problems have one reason, JavaScript is single-threaded.

Remember that JavaScript is single-threaded, and setTimeout does not implement multi-threading. The truth behind it is this:

The JavaScript engine runs in a single thread, and the browser only has one thread running at any time. JavaScript program.

The kernel of the browser is multi-threaded. They cooperate with each other under the control of the kernel to maintain synchronization. A browser implements at least three resident threads: JavaScript engine thread, GUI rendering thread, and browser event triggering thread.

*The JavaScript engine is based on event-driven single-thread execution. The JavaScript engine is always waiting for the arrival of tasks in the task queue, and then processes them. The browser has only one JavaScript thread running the JavaScript program at any time.

*The GUI rendering thread is responsible for rendering the browser interface. When the interface needs to be repainted (Repaint) or a reflow (Reflow) is caused by some operation, this thread will be executed. However, it should be noted that the GUI rendering thread and the JavaScript engine are mutually exclusive. When the JavaScript engine is executed, the GUI thread will be suspended, and GUI updates will be saved in a queue and will be executed immediately when the JavaScript engine is idle.

*Event triggering thread. When an event is triggered, the thread will add the event to the end of the pending queue and wait for processing by the JavaScript engine. These events can come from the code block currently executed by the JavaScript engine such as setTimeout, or from other threads in the browser kernel such as mouse clicks, Ajax asynchronous requests, etc. However, due to the single-threaded relationship of JavaScript, all these events have to be queued for processing by the JavaScript engine ( Asynchronous code will be executed only when no synchronous code is executed in the thread).

so, through the above explanation, all the above problems can be easily solved.

2. The delay time of setTimeout is 0

When the delay time of setTimeout is 0, think about how it will be executed?

For example, the following code:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <script>
   console.log(&#39;a&#39;);
   setTimeout(function(){
    console.log(&#39;b&#39;);
   },0);
   console.log(&#39;c&#39;);
   console.log(&#39;d&#39;);
  </script>
 </body>
</html>
Copy after login

The result of running the code is as follows:

Things about setTimeout in JavaScript

Assume that you already know the operating principle of Javascript single thread. Then, you may have this question: The setTimeout time is 0 and has not been added to the end of the processing queue. How can it be executed late? Shouldn't it be done immediately?

My understanding is that even if the setTimeout time is 0, it is still setTimeout, and the principle remains the same. So it will be added to the end of the queue and executed after 0 seconds.

Moreover, after searching for information, we found that setTimeout has a minimum execution time. When the specified time is less than that time, the browser will use the minimum allowed time as the time interval for setTimeout. That is to say, even if we change the milliseconds of setTimeout If set to 0, the called program will not start immediately.

What is the minimum time interval?

这和浏览器及操作系统有关。在John Resig的《Javascript忍者的秘密》一书中提到–Browsers all have a 10ms minimum delay on OSX and a(approximately) 15ms delay on Windows.(在苹果机上的最小时间间隔是10毫秒,在Windows系统上的最小时间间隔大约是15毫秒),另外,MDC中关于setTimeout的介绍中也提到,Firefox中定义的最小时间间隔(DOM_MIN_TIMEOUT_VALUE)是10毫秒,HTML5定义的最小时间间隔是4毫秒。

说了这么多,setTimeout的延迟时间为0,看来没什么意义嘛,都是放在队列后执行嘛。

非也,天生我材必有用,就看你怎么用咯。抛砖迎玉下。

1、可以用setTimeout的延迟时间为0,模拟动画效果哦。

详情请见下代码:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <div id="container" style="width:100px;height:100px;border:1px solid black;"></div>
  <div id="btn" style="width:40px;height:40px;line-height:40px;margin-top:20px;background:pink;">click</div>
  <script>
   window.onload = function(){
    var con = document.getElementById(&#39;container&#39;);
    var btn = document.getElementById(&#39;btn&#39;);
    //Params: i 为起始高度,num为预期高度
    function render(i, num) {
     i++;
     con.style.height = i + &#39;px&#39;;
     //亮点在此
     if(i < num){
      setTimeout(function() {
       render(i, num);
      },0);
     }
     else {
      con = null;
      btn = null;
     }
    };
    btn.onclick = function(){
     render(100, 200);
    };
   };
  </script>
 </body>
</html>
Copy after login

由于是动画,所以想看其效果,还请各位看官运行下代码哦。

代码第19行中,利用setTimeout,在每一次render执行完成(给高度递增1)后,由于Javascript是单线程,且setTimeout里的匿名函数会在render执行完成后,再执行render。所以可以实现动画效果。

2、可以用setTimeout的延迟时间为0,实现捕获事件哦。

当我们点击子元素时,我们可以利用setTimeout的特性,来模拟捕获事件。

请见如下代码:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <style>
   #parent {
    width:100px;
    height:100px;
    border:1px solid black;
   }
   #child {
    width:50px;
    height:50px;
    background:pink;
   }
  </style>
 </head>
 <body>
  <div id="parent">
   <div id="child"></div>
  </div>
  <script>
   //点击子元素,实现子元素的事件在父元素触发后触发
   window.onload = function(){
    var parent = document.getElementById(&#39;parent&#39;);
    var child = document.getElementById(&#39;child&#39;);
    parent.onclick = function(){
     console.log(&#39;parent&#39;);
    }
    child.onclick = function(){
     //利用setTimeout,冒泡结束后,最后输出child
     setTimeout(function(){
      console.log(&#39;child&#39;);
     },0);
    }
    parent = null;
    child = null;
   }
  </script>
 </body>
</html>
Copy after login

执行代码,点击粉红色方块,输出结果:

Things about setTimeout in JavaScript

三、setTimeout那些事儿之this

说到this,对于它的理解就是:this是指向函数执行时的当前对象,倘若没有明确的当前对象,它就是指向window的。

好了,那么我们来看看下面这段代码:

<!DOCTYPE html>
 <head>
  <title>setTimeout</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 </head>
 <body>
  <script>
   var name = &#39;!!&#39;;
   var obj = {
    name:&#39;monkey&#39;,
    print:function(){
     console.log(this.name);
    },
    test:function(){
     //this.print
     setTimeout(this.print,1000);
    }
   }
   obj.test();
  </script>
 </body>
</html>
Copy after login

通过chrome调试器,查看输出结果:

Things about setTimeout in JavaScript

咦,它怎么输出的是”!!”呢?不应该是obj里的”monkey”吗?!!

这是因为setTimeout中所执行函数中的this,永远指向window。

不对吧,那上面代码中的setTimeout(this.print,1000)里的this.print怎么指向的是obj呢?!!

注意哦,我这里说的是“延迟执行函数中的this”,而不是setTimeout调用环境下的this。

什么意思?

setTimeout(this.print,1000),这里的this.print中的this就是调用环境下的;

而this.print=function(){console.log(this.name);},这个匿名函数就是setTimeout延迟执行函数,其中的this.name也就是延迟执行函数中的this啦。

嘿嘿,这下明白了吧。

var age = 24;
function Fn(){
 this.age = 18;
 setTimeout(function(){
  //this代表window
  console.log(this);
  //输出24,而不是Fn的18
  console.log(this.age);
 },1000);
}
new Fn();
Copy after login

咦,那有个疑问,比如我想在setTimeout延迟执行函数中的this指向调用的函数呢,而不是window?!!我们该怎么办呢。

常用的方法就是利用that。

that?

对,that。利用闭包的知识,让that保证你传进去的this,是你想要的。

详情见下:

var age = 24;
function Fn(){
 //that在此
 var that = this;
 this.age = 18;
 setTimeout(function(){
  console.log(that);
  console.log(that.age);
 },1000);
}
new Fn();
Copy after login

还有一种方法就是,利用bind。

如下:

var age = 24;
function Fn(){
 this.age = 18;
 //bind传入this
 setTimeout(function(){
  console.log(this);
  console.log(this.age);
 }.bind(this),1000);
}
new Fn();
Copy after login

   


Statement of this Website
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

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

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

How to use JavaScript and WebSocket to implement a real-time online ordering system How to use JavaScript and WebSocket to implement a real-time online ordering system Dec 17, 2023 pm 12:09 PM

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to implement an online reservation system using WebSocket and JavaScript How to implement an online reservation system using WebSocket and JavaScript Dec 17, 2023 am 09:39 AM

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecasting system JavaScript and WebSocket: Building an efficient real-time weather forecasting system Dec 17, 2023 pm 05:13 PM

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

Simple JavaScript Tutorial: How to Get HTTP Status Code Simple JavaScript Tutorial: How to Get HTTP Status Code Jan 05, 2024 pm 06:08 PM

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

How to use insertBefore in javascript How to use insertBefore in javascript Nov 24, 2023 am 11:56 AM

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript and WebSocket: Building an efficient real-time image processing system JavaScript and WebSocket: Building an efficient real-time image processing system Dec 17, 2023 am 08:41 AM

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data

See all articles