Do you know how settimeout works? _javascript Tips

Source: Internet
Author: User
Tags anonymous setinterval wrapper

Let's take a look at the following code and guess the results:

var start = new Date;
settimeout (function () {
 console.log (' Elapsed time: ' + (new Date-start) + ' milliseconds ');
while (new Date-start < 1000) {}
Console.log (1);
function dosoming () {
 settimeout (function () {
  console.log (' Elapsed time: ' + (new Date-start) + ' millisecond ');
 },10);
dosoming ();
while (new Date-start <) {}
Console.log (2);

The result:
About 1 seconds after output: 1,
After about 1 seconds output: 2,
Then the output is now: Time Goes by: 2002 milliseconds
Final output: Time Goes by: 2003 milliseconds

Did you guess right?
the functions that are deferred by SetTimeout here are pushed to the last execution;
The principle is as follows:

In an existing browser environment, the JavaScript execution engine is single-threaded, and the main thread's statements and methods block the scheduled task from running, and there is a task queue outside the JavaScript execution engine, and when the SetTimeout () method is invoked in code, The registered delay method is hooked up to other modules in the browser kernel, and when the delay method arrives at the trigger condition, when the set delay time is reached, the module is then added to the task queue of the module. This process is independent of the main thread of the execution engine, and the execution engine executes the task sequentially from the task queue of the module when the main thread method has finished executing and arrives idle, which may be longer than the delay time set during the registration task.

In the idle state, the browser tries to extract the task from the module's task queue, which is called the event loop model.

Looking back at the previous code, the delay time for the second settimeout () is 10 milliseconds, triggering earlier than the first! Why is the result in the back? Because it was blocked by the previous code for about 1000.5~1001 milliseconds (depending on the browser's processing speed), wait for him to hang up to the processing module, wait until the trigger time is added to the task queue, the first settimeout () Delay method is already added to the module's task team, and the engine main thread is extracted sequentially , so, you should understand?

Now, if you change the while (new Date-start < 1000) {} to while (new Date-start < 189) {} or is a while (new Date-start < 190) { What is the result? I will not say more! Refresh the browser 20 times, you see the results!

While the SetInterval () method and settimeout () status are the same, when the SetInterval () method is invoked, the registered delay method hangs to the module processing, adding a method to be executed to the task queue whenever the triggering time arrives;

Here's a concrete look at settimeout syntax:
var Timeid = window.settimeout (func,delay,[param1,param2,...]);
var Timeid = window.settimeout (Code,delay);
settimeout and SetInterval are methods of the Window object (you can omit window), and the Second optional argument (IE9 and legacy unsupported) is the parameter passed to Func, which returns a numeric ID each time it is invoked ( Printing in the browser is just a number, and I print out in the webstorm found that it is actually an object, there are many attributes, this ID maintains its corresponding settimeout or setinterval information, mainly used in the middle of the module and the task queue to clear ( or off) them (using method Cleartimeout (ID) and clearinterval (ID)).
If you need to pass a parameter to your callback function, the following is the method of compatible IE

if (document.all &&!window.settimeout.ispolyfill) {
 var __nativest__ = window.settimeout;
 Window.settimeout = function (Vcallback, Ndelay, param1, param2,param3) {
 var Aargs = Array.prototype.slice.call ( arguments, 2);
 Return __nativest__ (vcallback instanceof function? function () {
  vcallback.apply (null, Aargs);
 }: Vcallback, ND Elay);
 };
 Window.setTimeout.isPolyfill = true;
}

A common error occurs in loops using closures

for (var i =0 i <10; i++) {
 settimeout (function () {
  console.log (i); 
 },1000);
} 

The above code will only output the number 100 times. Why? Shut the bag!

While the Console.log is invoked, although the anonymous function keeps a reference to the external variable i, the For loop ends and the value of I is modified to 10.

In order to get the desired result, you need to create a copy of the variable i in each loop.

In order to get the loop sequence number right, it's best to use an anonymous wrapper (which is what we usually call a self executing anonymous function).

for (var i =0 i <10; i++) {
 (function (e) {
  settimeout (function () {
   console.log (e); 
  },1000);
 }) (i);
}

The external anonymous function executes immediately and takes I as its parameter, at which point the e variable in the function has a copy of I.
When an anonymous function passed to SetTimeout executes, it has a reference to E, which is not changed by the loop.
There is another way to do the same: return a function from the anonymous wrapper. This is the same as the previous code effect.

for (var i-=0 i <10; i++) {
 settimeout ((function (e) {return
  function () {
   console.log (e);
  }
 }) (i), 1000)
}

Another important application: function throttling (throttle) and function dithering (debounce)
Please look at some of the information I collected from the Internet:
function throttling (throttle) and function javascript-for performance optimization (debounce)

Reference Links:
Https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout
http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.