Timer
setTimeout
is what we often use. It is used to call a function or calculate an expression after a specified number of milliseconds.
Syntax:
setTimeout(code, millisec, args);
Note: If the code is a string, it is equivalent to executing the
eval()
method to execute the code.
Of course, this article not only tells you how to use
setTimeout
, but also understands how it is executed.
1. Principle of setTimeout
Let’s look at a piece of code first:
var start = new Date(); var end = 0; setTimeout(function() { console.log(new Date() - start); }, 500); while (new Date() - start <= 1000) {}
In the above code, a
setTimeout
Timer, the delay time is 500 milliseconds.
Do you think the print result is: 500
But the fact is that it is beyond your expectation. The print result is like this (maybe it will be different when you print it out, but it will definitely be greater than 1000 Milliseconds):
#Why is this? The reason is that JavaScript is executed in a single thread. In other words, at any point in time, there is and is only one thread running the JavaScript program, and multiple pieces of code cannot be run at the same time.
Let’s take a look at JavaScript under the browser.
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. .
JavaScript引擎
is based on event-driven single-thread execution. The JavaScript engine has been waiting for the arrival of tasks in the task queue and then processed them. The browser has only one JavaScript thread running at any time. JavaScript program.
GUI渲染线程
is responsible for rendering the browser interface. This thread will be executed when the interface needs to be repainted (Repaint) or when a reflow (Reflow) is caused by some operation. 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.
事件触发线程
, 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 to wait for processing by the JavaScript engine. (Asynchronous code will be executed only when no synchronous code is executed in the thread).
Here, let’s review the original example:
var start = new Date(); var end = 0; setTimeout(function() { console.log(new Date() - start); }, 500); while (new Date() - start <= 1000) {}
Although the delay time of
setTimeout
is 500 milliseconds, Due to the existence of the
while
loop, the while loop will only jump out when the interval is greater than 1000 milliseconds. That is to say, before 1000 milliseconds, the while loop is occupying the JavaScript thread. In other words, only after waiting to jump out of while, the thread will become idle and execute the previously defined setTimeout.
Finally, we can conclude that
setTimeout
can only guarantee that the task (function that needs to be executed) will be inserted into the task queue to wait after the specified time, but it does not guarantee when the task will be executed. implement. Once the thread executing javascript is free, remove the task from the queue and execute it.
Because the JavaScript thread is not blocked due to any time-consuming operations, it can quickly take out the tasks in the queue and execute it. It is also this queue mechanism that creates the illusion of asynchronous execution for us.
2. A good partner of setTimeout "0"
Maybe you have seen the following code:
setTimeout(function(){ // statement}, 0);
The above code means immediate execution. The original intention is to execute the calling function immediately, but in fact, the above code is not executed immediately. This is because setTimeout has a minimum execution time. When the specified time is less than that time, the browser will use the minimum allowed time as setTimeout. time interval, that is to say, even if we set the delay time of setTimeout to 0, the called program does not start immediately.
The actual situation of different browsers is different. The time accuracy of IE8 and earlier IE is 15.6ms. However, with the emergence of HTML5, in advanced versions of browsers (Chrome, IE9+, etc.), the minimum time interval defined is not less than 4 milliseconds. If it is lower than this value, it will automatically increase, and in 2010 and later Adopted consistently across published browsers.
So, when we write
setTimeout(fn,0)
, we are actually implementing the queue jumping operation, requiring the browser to perform the callback "as quickly as possible", but how fast can it actually be? It all depends on the browser.
What is the use of
setTimeout(fn, 0)
? In fact, the utility lies in that we can change the order of task execution! Because the browser will execute the tasks accumulated in the setTimeout queue after completing the tasks in the current task queue.
By setting the task to be executed after delaying to 0s, you can change the order of task execution, delay the occurrence of the task, and make it execute asynchronously.
Let’s look at a very popular example on the Internet:
document.querySelector('#one input').onkeydown = function() { document.querySelector('#one span').innerHTML = this.value; }; document.querySelector('#second input').onkeydown = function() { setTimeout(function() { document.querySelector('#second span').innerHTML = document.querySelector('#second input').value; }, 0); };
`实例:实例
当你往两个表单输入内容时,你会发现未使用setTimeout函数的只会获取到输入前的内容,而使用setTimeout函数的则会获取到输入的内容。
这是为什么呢?
因为当按下按键的时候,JavaScript 引擎需要执行 keydown 的事件处理程序,然后更新文本框的 value 值,这两个任务也需要按顺序来,事件处理程序执行时,更新 value值(是在keypress后)的任务则进入队列等待,所以我们在 keydown 的事件处理程序里是无法得到更新后的value的,而利用 setTimeout(fn, 0),我们把取 value 的操作放入队列,放在更新 value 值以后,这样便可获取出文本框的值。
未使用setTimeout函数,执行顺序是:`onkeydown => onkeypress => onkeyup
使用setTimeout函数,执行顺序是:
onkeydown => onkeypress => function => onkeyup`
虽然我们可以使用
keyup
来替代
keydown
,不过有一些问题,那就是长按时,
keyup
并不会触发。
长按时,keydown、keypress、keyup的调用顺序:
keydown keypress keydown keypress ... keyup
也就是说keyup只会触发一次,所以你无法用keyup来实时获取值。
我们还可以用
setImmediate()
来替代
setTimeout(fn,0)
:
if (!window.setImmediate) { window.setImmediate = function(func, args){ return window.setTimeout(func, 0, args); }; window.clearImmediate = window.clearTimeout; }
setImmediate()`方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数,必选的第一个参数func,表示将要执行的回调函数,它并不需要时间参数。
注意:目前只有IE10支持此方法,当然,在Nodejs中也可以调用此方法。
3、setTimeout的一些秘密
3.1 setTimeout中回调函数的this
由于setTimeout() 方法是浏览器 window 对象提供的,因此第一个参数函数中的this其实是指向window对象,这跟变量的作用域有关。
看个例子:
var a = 1; var obj = { a: 2, test: function() { setTimeout(function(){ console.log(this.a); }, 0); } }; obj.test(); // 1
不过我们可以通过使用bind()方法来改变setTimeout回调函数里的this
var a = 1; var obj = { a: 2, test: function() { setTimeout(function(){ console.log(this.a); }.bind(this), 0); } }; obj.test(); // 2
3.2 setTimeout不止两个参数
我们都知道,setTimeout的第一个参数是要执行的回调函数,第二个参数是延迟时间(如果省略,会由浏览器自动设置。在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。)
其实,setTimeout可以传入第三个参数、第四个参数….,它们表示神马呢?其实是用来表示第一个参数(回调函数)传入的参数。
setTimeout(function(a, b){ console.log(a); // 3 console.log(b); // 4},0, 3, 4);
以上就是JavaScript 开发者应该知道的 setTimeout 秘密 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

Dreamweaver CS6
Visual web development tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Zend Studio 13.0.1
Powerful PHP integrated development environment

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool