问题
I set up an simple experiment out of curiosity:
I dynamically generated a div with the class
box
before attaching a click listener to it with JQuery.I then created a duplicate of this, except this time, I added a timeout of zero before the
box
element is generated.
As shown in the JSFiddle, using a timeout of zero results in the failure of the click's intended result event to be triggered.
This script results in an alert on click.
$(document).ready(function(){
//setTimeout(function(){
$(".wrapper").html('<div class="box"></div>');
//},0)
$(".box").click(function(){
console.log("A box was clicked!");
});
});
This script does not.
$(document).ready(function(){
setTimeout(function(){
$(".wrapper").html('<div class="box"></div>');
},0)
$(".box").click(function(){
console.log("A box was clicked!");
});
});
Why does a timeout of zero cause the element to be (I assume) generated after the click event listener is attached via JQuery?
Does setTimeout(functon(){//do stuff},0)
cause a minuscule execution delay for it's contained function? If so, why does this happen?
回答1:
JavaScript is singled-threaded and event-based. setTimeout()
immediately creates a new event that needs to be processed, but the current "event" (function/code) must be finished, first.
Excerpt from Events and timing in-depth:
When setTimeout gets 0 as the last argument, it attempts to execute the func as soon as possible.
The execution of func goes to the Event queue on the nearest timer tick. Note, that’s not immediately. No actions are performed until the next tick.
Other detailed explanations:
- How JavaScript Timers Work
- Effect of Setting setTimeout to 0 and Explanation of JavaScript's Single Threaded, Non Blocking I/O, Async Event Driven Model
Note: I often use this setTimeout(func, 0)
"trick" to execute code that must be run after a DOM manipulation or the current function is completed.
回答2:
I think that you do not anderstand the behaviour of setTimeout(function (){}, 0);
Let's analyse the code step by step. Code 1:
- Creates a .box element and append in the DOM.
- Search for .box elements in the DOM.
- Handles the click event to that elements.
If you clic on the .box element then you will get execute the click callback.
The second code:
- You prepare a function to be executed in the future. This future will be in, at least, 0 ms, but still in the future. It is an asynchronous execution
- Search for .box elements in the DOM, but there aren't elements.
- Handles the click event to that elements, but there aren't elements.
- After the execution flux, the setTimeout function callback is executed. Then you create your .box element.
Unfortunately, you didn't applied the callback to any element because it was not created during the click handling.
回答3:
Play around with JSPerf. It seems setTimeout is considerably slower.
回答4:
It causes the function to be executed asynchronously.
It executes instantly but asynchronously, that means that it doesn't follow the normal flow, so It could be executed after or before the next function, you don't have control over that anymore.
回答5:
What setTimeout(someFunction, timeInMS)
means is that JavaScript will call someFunction
AT LEAST timeInMS
milliseconds in the future.
来源:https://stackoverflow.com/questions/24152790/does-settimeoutfuncton-do-stuff-0-cause-a-minuscule-execution-delay-for