Home  >  Article  >  Web Front-end  >  How setTimeout sets time to 0

How setTimeout sets time to 0

小云云
小云云Original
2018-03-14 09:07:591981browse

This article mainly introduces you to the relevant content about setting the setTimeout time to 0. setTimeout() is a method belonging to window, but we all omit the top-level container name of window, which is used to set a time. When it arrives, a specified method will be executed. The following article mainly introduces you to the relevant information about setting the setTimeout time to 0. Friends in need can refer to it.

1. Appetizer, what is setTimeout

First look at the explanation of setTimeout on w3school

setTimeout(fn,millisec) method is used to call a function or calculated expression after a specified number of milliseconds.

It’s very simple, setTimeout() Only execute fn once, when it is executed depends on the number of milliseconds set by the second parameter millisec, so many people are used to it It is called delay, which is nothing more than delaying for a period of time before executing the code inside.


setTimeout(function(){
 console.log('我是setTimeout');
}, 1000);

Under normal circumstances, I am setTimeout. This sentence will not be output immediately but will be output in the browser console after 1000 milliseconds.

2. Main dish, js is single-threaded

OK, let’s look at an example. What is the output of this example? ?


setTimeout(function(){
 console.log(1);
}, 0);
console.log(2);
console.log(3);

To the surprise of some people, the results were 2, 3, 1. This doesn't seem to follow the routine. It obviously waits for 0 milliseconds, that is, it outputs directly without waiting. Why is 1 output at the end?

This requires clarification of a very important concept: js is single-threaded. Single-threading means that all tasks need to be queued, and the next task will not be executed until the previous task is completed. If the previous task takes a long time, the next task will have to wait.

In fact, it’s easy to understand. Just like when everyone goes to the supermarket to buy things, everyone who buys things needs to line up at the checkout counter to check out. Under normal circumstances, each checkout counter can only serve one person at a time. The customer checks out. Only after this customer checks out can the next customer be served.

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 events. Trigger thread.

  • The JavaScript engine is based on event-driven single-thread execution. The JS engine has been waiting for the arrival of tasks in the task queue and then processed them. The browser has only one JS thread at any time. Run JS program.

  • The GUI rendering thread 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 JS engine are mutually exclusive. When the JS engine is executed, the GUI thread will be suspended, and GUI updates will be saved in a queue and executed immediately when the JS engine is idle.

  • Event trigger 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 JS 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 JS, all these events have to be queued for processing by the JS engine. (Asynchronous code will be executed when no synchronous code is executed in the thread)

In fact, when js code execution encounters setTimeout(fn,millisec) , the fn function will be placed in the task queue. When the js engine thread is idle and reaches the time specified by millisec, fn will be placed in the js engine thread for execution.

setTimeout(fn,0) means to specify a task to be executed in the earliest available idle time of the main thread, that is, to be executed as early as possible. It adds an event at the end of the "task queue", so it will not be executed until the synchronization task and the existing events in the "task queue" have been processed.

HTML5 standard stipulates that the minimum value (shortest interval) of the second parameter of setTimeout() shall not be less than 4 milliseconds. If it is lower than this value, it will automatically increase. Prior to this, older browsers set the minimum interval to 10 milliseconds. In addition, those DOM changes (especially those involving page re-rendering) are usually not executed immediately, but every 16 milliseconds. At this time, the effect of using requestAnimationFrame() is better than setTimeout() .

It should be noted that setTimeout() only inserts the event into the "task queue". The main thread must wait until the current code (execution stack) is finished executing before the main thread executes the specified task. Callback. If the current code takes a long time, you may have to wait for a long time, so there is no way to guarantee that the callback function will be executed at the time specified by setTimeout().

3. Dessert, the wonderful uses of setTimeout

In fact, setTimeout has some wonderful uses, here are a few.

Function debounce

让一个函数在一定间隔内没有被调用时,才开始执行被调用方法。比如当你在使用 google 搜索内容的时候,有些关键词输入到一半,谷歌会展示一个可选列表,根据你当前输入的内容作出的一个猜测联想。需要监听文字改变,每一次改变都会调用一次回调函数,现在需要的一种实现是在用户停止键盘事件一段时间后,去发送一个请求。


var debounce = function(method, context) {
 clearTimeout(method.tId);
 method.tId = setTimeout(function(){
  method.call(context);
 },100);
}

轮训任务

js中可以使用setInterval开启轮询,但是这种存在一个问题就是执行间隔往往就不是你希望的间隔时间。

比如有个轮询任务间隔是100ms,但是执行方法的时间需要450ms,那么在200ms、300ms、400ms本来是计划中执行任务的时间,浏览器发现第一个还未执行完,那么就会放弃2、3、4次的任务执行,并且在500ms之后再次执行任务,这样的话,其实再次执行的间隔就只有50ms。使用setTimeout构造轮询能保证每次轮询的间隔。


setTimeout(function () {
 console.log('我被调用了');
 setTimeout(arguments.callee, 100);
}, 100);

延迟js引擎的调用


var p = document.createElement('p');
p.innerHTML = '我是一个p';
p.setAttribute('style', 'width:200px; height:200px;background-color:#f00; ');
document.body.appendChild(p);
setTimeout(function() {
 console.log('我被调用了');
}, 1000);

虽然setTimeout有一些妙用,但是他确实是在宏观任务队列中新增任务了,所以万万不能滥用啊。

相关推荐:

JS中setInterval和setTimeout实例分析

JavaScript中setTimeout()的使用详解

javascript函数setTimeout带参数用法实例详解

The above is the detailed content of How setTimeout sets time to 0. 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