JS i / o序列

时间:2013-08-25 20:02:03

标签: javascript asynchronous timeout output synchronous

我有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);
}

所以我期待以下内容:

  1. 这将写成'超时已经开始!'在页面加载后立即在页面上。
  2. 接下来将写成'你好,我醒了!';
  3. 然后在函数超时中循环内生成的日志将在控制台中连续输出。 但没有那种。实际上,首先出现的是函数timeout()中的循环。 所以我看到所有这些日志消息,只有 后才能在页面上写入函数startIt()和mssTmt()中获取消息。我必须承认这对我来说非常不寻常。为什么这么一个序列? 我有一些推定,但当然从真正的JS大师那里得到确切的解释会好得多! Plssss!

  4. RoryKoehein回答后,

    更新 我通过链接阅读了他给我的东西,但有些事情仍然难以理解。

    我稍微更改了我的代码。现在有来电者:

    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(超时,[延迟]); 它一直不可预测:

    • 如果我将延迟设置为0,则仅在循环后才输出 函数timeout()完成
    • 如果我增加延迟,有时会产生输出(startIt(),mssTmt()) BEFORE循环,有时在循环之后,取决于延迟值。

    但最奇怪的是,在所有这些尝试中,即使具有相同的延迟值,I / O的顺序也会变得不同!例如: 的setTimeout(超时,3); 有时会导致首先在函数startIt(),mssTmt()中发生输出,有时反之亦然 - timeout()。 说实话,我不知道这是什么意思......

1 个答案:

答案 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()?