There is a button on the page as follows
<button onclick="index.testClick()" >开始</button>
The js script corresponding to this page is as follows
var index = {
testClick: function () {
index.createBtn(function() {
index.sleep(10000);
});
},
sleep: function (n) {
var start = new Date().getTime();
while (true) {
if(new Date().getTime() - start > n)
break;
}
},
createBtn: function (func) {
var button = $('<button>测试</button>');
button.bind("click",function(){
button.remove();
func();
});
$('body').prepend(button);
},
};
Why after clicking the start button and then clicking the test button, the test button actually sleeps (this was noticed on the synchronized $.ajax request, and is simulated here with a loop) before being removed? Only by wrapping sleep in setTimeout can we get the desired effect...?
某草草2017-05-19 10:18:13
This question is indeed a little bit... At first glance, I thought that the code sleeps for 10 seconds on purpose. However, the questioner can't understand it. From the comments in the comment area above, I probably know what the question is...
This stuff is related to the browser UI thread. The browser is single-threaded (this thread is generally called the browser UI thread).
Chapter 6 of "High-Performance JavaScript" Quickly Responsive User Interface, there are two paragraphs:
Most browsers have a single processing process that is shared between two tasks: the JavaScript task and the user interface update task. Only one of these operations can be performed at a time, which means that the user interface cannot react to input while the JavaScript code is running, and vice versa. In other words, when JavaScript is running, the user interface is "locked". Managing JavaScript runtime is important to the performance of web applications.
The process shared by JavaScript and UI updates is often called the "browser UI thread". The work of the UI thread is based on a simple queue system, and tasks are saved in the queue until the process is idle. Once idle, the next task in the queue is re-extracted and run. These tasks are either running JS code or performing UI updates, including redrawing and reflowing.
function(){
button.remove();
func();
}
This is the processing function of the click event. After js removes the DOM node, func() will continue to run immediately. After 10 seconds, the process will be idle before running the next task and updating the user interface. Only then will the button disappear from the page.
A question in the comment area of another answer above, ‘Why doesn’t this happen when adding it?’
The added function is like this,
createBtn: function (func) {
var button = $('<button>测试</button>'); //生成button
button.bind("click",function(){ //给button绑点击事件
button.remove();
func();
});
$('body').prepend(button); //把button加到body上
},
This process does not run func(). Try moving this function out and changing it to this
createBtn: function (func) {
var button = $('<button>测试</button>');
button.bind("click",function(){
button.remove();
});
$('body').prepend(button);
func();
},
Definitely blocked too
为情所困2017-05-19 10:18:13
It should be that you blocked the thread, causing graphics rendering to get stuck
Even if the button has been deleted from the dom tree.
But the graphics did not redraw the new DOM tree where the button does not exist.
淡淡烟草味2017-05-19 10:18:13
I thought it was simple before. It should be the same as what was said downstairs, the screen rendering was stuck.
For example, print the log before func();:
console.log(func);
After the output logo appears, it gets stuck. The complete content is not displayed until sleep is executed:
When sleep is executed, the page is blocked and cannot be operated at all. At the same time, the CPU usage is very high (because there is no interval in theory in this loop). This may be the reason why it is stuck.