我有3个被调用的函数:
<body onLoad="startIt(),mssTmt(),timeout()">
他们是:
function startIt(){
document.write('Timeout has started!');
}
function timeout(){
function sleep(milliSeconds) {
var startTime = new Date().getTime();
var cnt=0;
while (new Date().getTime() < startTime + milliSeconds){
cnt++;
if(cnt%1000000==0)
console.log('time expired: '+(new Date().getTime())+'<br>');
}
}
sleep(3000);
}
function mssTmt(){
var greeting = 'Hello, I am awake!';
document.write('<hr>'+greeting);
}
所以我期待以下内容:
更新 我通过链接阅读了他给我的东西,但有些事情仍然难以理解。
我稍微更改了我的代码。现在有来电者:
function getStarted(){
console.log(new Date().getTime()+' > getStarted() has been called');
try{
startIt();
mssTmt();
timeout();
}catch(e){
alert(e.message);
}
}
...
<a href="javascript:void();" onclick="getStarted();" id="getstarted">Get started!</a>
相反
<body onLoad="startIt(),mssTmt(),timeout()">
首先会发生这样的事情:如果我在调用每个函数之前添加一个alert(),那么序列与放在代码中的顺序完全相同 - startIt(),mssTmt(),timeout( )。在单击警报弹出窗口之前,所有实现都将被阻止。请见illustration。 如果我删除警报,它就像之前一样工作(请参阅问题的起点)。因此,如果警报阻止所有进程处理它改变执行顺序(i / o)的原因? 接下来,当我尝试通过setTimeout()调用函数timeout()时,我发现了一个奇怪的脚本行为; 这里:http://javascript.info/tutorial/events-and-timing-depth#the-settimeout-func-0-trick写的是 setTimeout(..,0)技巧用于在堆叠事件之后执行代码并修复与时序相关的问题。 如果我像这样修改代码: 的setTimeout(超时,[延迟]); 它一直不可预测:
但最奇怪的是,在所有这些尝试中,即使具有相同的延迟值,I / O的顺序也会变得不同!例如: 的setTimeout(超时,3); 有时会导致首先在函数startIt(),mssTmt()中发生输出,有时反之亦然 - timeout()。 说实话,我不知道这是什么意思......
答案 0 :(得分:1)
这很好地解释了它:http://javascript.info/tutorial/events-and-timing-depth#javascript-execution-and-rendering
最重要的是:
在大多数浏览器中,渲染和JavaScript使用单个事件队列。这意味着在JavaScript运行时,不会进行渲染。
while循环完全阻止线程三秒钟。 document.write调用被添加到事件队列中,甚至可能被执行,但paint-event在JS不再阻塞之后发生。
如果您打开Chrome的开发人员工具时间轴,则可以准确了解浏览器正在执行的操作(https://developers.google.com/chrome-developer-tools/docs/timeline)。
偏离主题:我认为这是测试代码。绝不应该在生产中使用这样的东西。在body标签[1]中内联堆叠多个函数,使用document.write [2]和阻塞while循环都是不好的做法[3]。
1 window.onload vs <body onload=""/> 2 Why is document.write considered a "bad practice"? 3 What is the JavaScript version of sleep()?