What does settimeout (fn,0) mean under JavaScript?

Source: Internet
Author: User

Original: What does the settimeout (fn,0) under JavaScript mean?

I'm very sensitive to settimeout and stuff like that in the recent study of asynchronous programming. On the segmentfault saw a problem "about settimeout time set to 0 o'clock": the questioner read an article, the original explanation of the SetTimeout delay time is 0 when things will happen, the questioner raised a few points in several articles. After reading the article, I found that the author of the original text had a little discrepancy with settimeout's understanding and his own cognition, so he wrote the code for the test to answer. This article was eventually written.

This article reads as follows:

  • Cause
  • Single thread of JavaScript
  • What it means to be behind settimeout.
  • References and references

JavaScript-front-end development Communication group: 377786580

Cause

The morning on the Segmentfault saw this problem "about settimeout time set to 0 o'clock" (Note: Segmentfault is adjusting the record, if not accessible, click here), the original questioner noted the source of the problem: JS SetTimeout delay time is 0 in detail ". The source of this problem is also reproduced, I later found the source.
In the article on the source of the problem (the latter), it tells the JS is a single-threaded engine: It puts the task in the queue, does not synchronize to execute, must complete a task before starting another task.
Then, the reproduced article lists and supplements the original chestnut:

<! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01//en" "Http://www.w3.org/TR/html4/strict.dtd" >

Code run instance please poke here.
There is such a passage in the original text that the description is somewhat abstract:

When the JavaScript engine executes onmousedown, it is not possible to process the focus and select methods of the element you just created because there is no multi-threaded synchronous execution, since both methods are not in the queue, and after completing OnMouseDown, JavaScript The engine has dropped both of these tasks, as in the first case. In the second case, the settimeout can get the desired result by jumping the task from one queue to a new queue.

I feel very strange when I see this place. Since the argument that this task will be discarded, the browser will never do so as long as the other events are discarded in the event-triggered function, so I write the test code:

    window.onload = function () {        //第一个例子:未使用setTimeout        get('makeinput').onmousedown = function () {            var input = document.createElement('input');            input.setAttribute('type', 'text');            input.setAttribute('value', 'test1');            get('inpwrapper').appendChild(input);            //按照文中的理论,这里的click不会被触发,但它却成功触发了            get('inpwrapper').click();//触发了inpwrapper的onclick事件        }        get('inpwrapper').onclick = function () {            alert('linkFly');        };    }

The following onclick () is finally executed: "Linkfly" pops up.

In the text reproduced in order to make a point of view, and put forward a third example:

Here, you can take a look at example 3, its task is to update the input text in real-time, please try now, you will find that the preview area is always behind a beat, such as you lose A, the preview area does not appear a, immediately after the input B, a is not leisurely to appear.

In the end, the solution is to use settimeout to adjust the browser's code task to run the queue again.

    var domInput = get('input');    domInput.onkeypress = function () {        setTimeout(function () {            //第三个例子的问题就这样就会被解决            get('preview').innerHTML = domInput.value;        })    }

The original text and reproduced in the article are settimeout (fn,0) thought, but the original points out the problem is very porous, so just out of this article, our text, now began.

Single thread of JavaScript

First, let's look at JavaScript under the browser:
The kernel of the browser is multi-threaded, and they mate with each other in the kernel to keep in sync, and a browser implements at least three resident threads: JavaScript engine thread, GUI render thread, browser event trigger thread.

  • JavaScript engine is based on the event-driven single-threaded execution, the JS engine has been waiting for the task queue of the arrival of the task, and then to deal with, the browser whenever there is only one JS thread running JS program.
  • The GUI rendering thread is responsible for rendering the browser interface, which executes when the interface needs to be redrawn (Repaint) or when a return (reflow) is caused by an operation. However, it is important to note that the GUI rendering thread is mutually exclusive to the JS engine, and when the JS engine executes, the GUI thread is suspended, and the GUI update is saved in a queue until the JS engine is idle and executed immediately.
  • An event triggers a thread that, when an event is triggered, adds the event to the end of the queue to be processed and waits for the JS engine to process. These events can come from code blocks currently executing by the JavaScript engine, such as settimeout, other threads from the browser kernel such as mouse clicks, Ajax asynchronous requests, and so on, but because of the JS single-threaded relationship all of these events are queued for the JS engine to process. (Asynchronous code is executed only if no synchronization code is executed in the thread)

JS single-threaded in this section of the interview code is particularly obvious (understand, please do not try ...) The browser will feign death):

        var isEnd = true;        window.setTimeout(function () {            isEnd = false;//1s后,改变isEnd的值        }, 1000);        //这个while永远的占用了js线程,所以setTimeout里面的函数永远不会执行        while (isEnd);        //alert也永远不会弹出        alert('end');

In my work in the understanding of JS, personally think that the task unit JS is a function. That is, a function represents a task, and the function does not end, and the current task in the browser does not end.
In the above code, the current task is never executed because of the while execution, so the subsequent settimeout will never be executed. It is in the task queue of the browser:

What it means to be behind settimeout.

This article has been using settimeout for us to show and understand JS single-threaded design, but it was wrong to use the event to demonstrate, and excessive interpretation of the event.
Here the original text and reprint of the article ignored these basic events triggered, but also chose two sets of their own design is more complex api:onmousexxx and onkeyxxx system.

API triggering sequence for ONKEYXXX systems

And I personally understand that they correspond to the function:

  • OnKeyDown-Primary gets and handles the current press key, for example, press ENTER to commit. At this level, the values of the associated DOM elements are not updated.
  • onkeypress-the main acquisition and processing of long keys, because onkeypress in the case of long press the keyboard will repeatedly trigger until released, here does not update the value of the relevant DOM elements, it is worth noting that the value is not updated after KeyPress, So when a long press on the keyboard repeatedly triggers the onkeypress event, the latter trigger onkeypress can get the value of the previous onkeypress. So there's a onkeypress. Each value will be the last value instead of the latest value.
  • OnKeyUp-The value of the DOM element that triggered the onkeyup has been updated here to get the most recent value, so the value of the relevant DOM element is mainly processed here.

The process is the picture above:

onkeydown = onkeypress = onkeyup

After using settimeout, the flow should be the following:

onkeydown = onkeypress = function = onkeyup

After using settimeout (fn,0), our function functions are inserted after onkeypress. As mentioned above, the browser updates the state of the associated DOM element (Input[type=text] value) after onkeypress, so we can get the latest value in the function.
So we hang up inside the onkeypress settimeout can get the correct value, the following code can test the process after using settimeout (fn,0):

    window.onload = function () {        var domInput = get('input'), view = get('preview');        //onkeypress兼容性和说明:http://www.w3school.com.cn/jsref/jsref_events.asp        domInput.onkeypress = function () {            setTimeout(function () {                //这个函数在keypress之后,keyup之前执行                console.log('linkFly');            });        };        domInput.onkeyup = function () {            console.log('up');        };    };

And then we'll talk about Example 1 and Example 2 in the original code, the difference between Example 1 and Example 2 is here:

        //示例1        input.focus();        input.select();                //示例2        setTimeout(function () {            input.focus();            input.select();        }, 0);

The original article says that the focus () and select () of example 1 were discarded in the onmousedown event, resulting in the unchecked, but the original author ignores the event that he registered: onmousedown.
For the moment we don't discuss the other APIs of the ONMOUSEXXX system, we only focus on and click on the relevant, their order of execution is:

  • MouseDown-mouse button pressed
  • MouseUp-mouse button release
  • Click-Finish clicking

We created a new input in onmousedown and checked the value of input (called Input.focus (), Input.select ()).
So why hasn't it been chosen? So, let's do a test to see if our onfocus was dropped or triggered. We rewrite the original code:

    window.onload = function () {        var makeBtn = get('makeinput');        //观察onmouseXXX系完成整个单击的顺序        makeBtn.onmousedown = function (e) {            console.log(e.type);            var input = document.createElement('input');            input.setAttribute('type', 'text');            input.setAttribute('value', 'test1');            get('inpwrapper').appendChild(input);            input.onfocus = function () {//观察我们新生成的input什么时候获取焦点的,或者它有没有像原文作者说的那样被丢弃了                console.info('input focus');            };            input.focus();            input.select();        }        makeBtn.onclick = function (e) {            console.log(e.type);        };        makeBtn.onmouseup = function (e) {            console.log(e.type);        };        makeBtn.onfocus = function () {//观察我们生成按钮什么时候获取焦点的            console.log('makeBtn focus');        }    };

The result of the code run is this:

Our input focus is executing-so why doesn't it get the focus? Let's look at the following function: We clicked on the button, after the MouseDown, only to get the focus, that is to say: our input has already got the focus (), but after onmousedown, we click on the button to delay the trigger of their own onfocus (), Causes our input to be overwritten.
We add settimeout to test:

    window.onload = function () {        var makeBtn = get('makeinput');        makeBtn.onmousedown = function (e) {            console.log(e.type);            var input = document.createElement('input');            input.setAttribute('type', 'text');            input.setAttribute('value', 'test1');            get('inpwrapper').appendChild(input);            input.onfocus = function () {                console.info('input focus');            };            //我们加上setTimeout,看看会发生什么            setTimeout(function () {                input.focus();                input.select();            });        }        makeBtn.onclick = function (e) {            console.log(e.type);        };        makeBtn.onmouseup = function (e) {            console.log(e.type);        };        makeBtn.onfocus = function () {            console.log('makeBtn focus');        }    };

The result of the execution is this:

You can see that when we click the "Generate" button, the focus of the button is executed correctly before the input focus is executed.
In Example 1, we performed Input.focus () in onmousedown () causing input to get focus, and after onmousedown, we clicked on the button to get its focus, causing us to input just get the hand not roasts the focus of the heat is shifted.
With the code in Example 2, we delay the focus, and when the button gets the focus, our input grabs the focus, so after using settimeout (fn,0), our input can get focus and select the text.
The timing of the focus (), which is worth thinking about here, is based on the test observation that the focus event appears to be mounted on the last side of the MouseDown, rather than hanging directly behind the MouseDown. It and MouseDown seem to be one.
The task flow before we use settimeout is like this (that is, in the previous task,=> represents after the previous task):

OnMouseDown---onmousedown, Input.focus (), Button.onfocus = onmouseup = onclick

The task flow after we used the settimeout is this:

onmousedown-Button.onfocus = Input.focus = onmouseup = onclick

And from the above process we learned that the other news, we can also hang Input.focus in MouseUp and click, because before these events, our button has been the focus, no longer grab our focus.

        makeBtn.click = function (e) {            console.log(e.type);            var input = document.createElement('input');            input.setAttribute('type', 'text');            input.setAttribute('value', 'test1');            get('inpwrapper').appendChild(input);            input.onfocus = function () {//观察我们新生成的input什么时候获取焦点的                console.info('input focus');            };            input.focus();            input.select();        }

We should recognize that using settimeout (fn,0) features can help us to fix the next task of the browser in some extreme scenarios.

Here, we can already negate the original saying: "The JavaScript engine has discarded these two tasks."
I still believe that the browser is Love us (except IE6 and mobile side some Xxoo browser!!!!) The browser does not simply discard the code that we toil to write, most of the time, just because we don't see the truth behind it.

When we step into the world of computers and write "Hello Worlds," we should be convinced that in this binary world there is always truth.

References and references
  • JavaScript async mechanism
  • What is Event Loop
  • JavaScript Threading Explained

JavaScript-front-end development Communication group: 377786580

Linkfly Original: http://www.cnblogs.com/silin6/p/4333999.html Source: www.cnblogs.com/silin6/statement: Hey! You cuff the above a big paragraph, I think you should not mind by the way, I hope you can in every reference to retain this paragraph of the statement, respect for the author's hard work, this article and blog Park to share.

What does settimeout (fn,0) mean under JavaScript?

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.