我有 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);
}
所以我期待以下内容:
- 它会写成“超时已开始!” 在页面加载后立即在页面上。
- 接下来会写“你好,我醒了!”;
- 然后在函数超时的循环中生成的日志会依次输出到控制台。但没有那种东西。实际上,首先出现的是函数 timeout() 中的循环。因此,我看到了所有这些日志消息,然后才在页面上编写的函数 startIt() 和 mssTmt() 中收到消息。我必须承认这对我来说看起来很不寻常。为什么会有这样的顺序?我有一些假设,但当然最好从真正的 JS 大师那里得到准确的解释!请!
在RoryKoehein回答后更新我阅读了他通过链接给我的东西,但有些东西仍然难以理解。
我稍微改变了我的代码。现在有调用者:
function getStarted(){
console.log(new Date().getTime()+' > getStarted() has been called');
try{
startIt();
mssTmt();
timeout();
}catch(e){
alert(e.message);
}
}
…</p>
<a href="javascript:void();" onclick="getStarted();" id="getstarted">Get started!</a>
反而
<body onLoad="startIt(),mssTmt(),timeout()">
首先会发生这样的事情:如果我在调用每个函数之前添加一个 alert(),则序列与它在代码中的顺序完全相同 - startIt()、mssTmt()、timeout()。在我单击警报弹出窗口之前,所有实现都被阻止。请看插图。如果我删除警报,它会像以前一样工作(请参阅问题的起点)。因此,如果警报阻止所有进程,为什么它会更改执行顺序 (i/o)?接下来,当我尝试通过 setTimeout() 调用函数 timeout() 时,我注意到一个奇怪的脚本行为;在这里:http: //javascript.info/tutorial/events-and-timing-depth#the-settimeout-func-0-trick写到 setTimeout(.., 0) 技巧用于在堆叠事件之后执行代码并修复与时序相关的问题。如果我这样修改代码: setTimeout(timeout,[delay]); 它总是不可预知的:
- 如果我将延迟设置为 0,则它仅在函数 timeout() 中的循环完成后才输出
- 如果我增加延迟,有时它会在循环之前输出 (startIt(),mssTmt()),有时在循环之后,取决于延迟值。
但最奇怪的是,即使延迟值相同,在所有这些尝试中,I/O 的顺序都变得不同了!例如:setTimeout(timeout,3); 有时它会导致首先在函数 startIt()、mssTmt() 中发生输出,有时反之亦然 - timeout()。老实说,我不知道这是什么意思……