JSFiddle - React, Tailwind, and code Playground
HTML
<a href="#" id="button">Click me</a>
<p>
Click the link once to start a 1-second loop. During that 1 second, click again. Each time you click, you'll trigger an <code>onclick</code> callback that will set <code>x</code> to <code>"interrupted"</code>. At some point, the <code>func2</code> timeout will set <code>x</code> to <code>good</code>. However, if you click the link several times, some of those callbacks will run after <code>func2</code>. An alert will pop up 500ms after the loop to tell you the value of <code>x</code>.
</p>
<p>
The question is: Is there any way to ensure that the value of <code>x</code> will be <code>good</code>? That is, how can you make <code>func2</code> run after all the input events that the user caused during <code>func1</code> have resolved?
</p>
<p>
Head to <a href="http://stackoverflow.com/questions/6391536/dom-input-events-vs-settimeout-setinterval-order">http://stackoverflow.com/questions/6391536/dom-input-events-vs-settimeout-setinterval-order</a> if you think you have an answer.
</p>
JavaScript
var func1, func2, x, start, interrupt, clickCount;
var button = document.getElementById('button');
var start = function() {
clickCount = 1;
button.onclick = interrupt;
func1();
button.style.visibility = 'hidden';
// button.onclick = null; // this would prevent any interrupt clicks from registering
setTimeout((function() {
alert('clicks: ' + clickCount + ', state: ' + x);
button.style.visibility = 'visible';
button.onclick = start;
}), 500);
return false;
};
var interrupt = function() {
clickCount++;
x = 'interrupted';
return false;
}
button.onclick = start;
func1 = function() {
var startTime;
startTime = (new Date).getTime();
while ((new Date).getTime() - startTime < 1000) {
continue;
}
setTimeout(func2, 0);
};
func2 = function() {
button.onclick = null; // prevent clicks after first timeout
setTimeout(function() {
x = 'good';
}, 0);
};