2016-01-20 75 views
0

我有这样的代码http://jsfiddle.net/ee1xuaqs/1/事件不排队正确

function long_running(status_div) { // does something for 2-3 seconds 

    var result = 0; 
    // Use 1000/700/300 limits in Chrome, 
    // 300/100/100 in IE8, 1000/500/200 in FF 
    alert('running'); 
    for (var i = 0; i < 1000; i++) { 
     for (var j = 0; j < 700; j++) { 
      for (var k = 0; k < 300; k++) { 
       result = result + i + j + k; 
      } // end inner 
     } // end outer for 
    } 

} 

$('#do_ok').on('click', function() { 
    $('#status_ok').text('calculating....'); 
    window.setTimeout(function(){ long_running('#status_ok') }, 1000); 
    $('#status_ok').text('calclation done'); 
}); 

随着这个HTML:

<table border=1> 
    <tr><td><button id='do_ok'>Do long calc</button></td> 
     <td><div id='status_ok'>Not Calculating yet.</div></td> 
    </tr> 
</table> 

现在,当我点击按钮,我得到“计算完成”表示('正在计算...'可能闪烁一毫秒或两秒)。

据我所知,$('#do_ok').on中的这3个命令中的每一个都创建了一个单独的事件,两个用于更新DOM,另一个用于setTimeout,在1秒后完成。对于jQuery DOM更新命令,DOM会立即更新,但是,它们也会创建DOM-repaint事件,并像往常一样进行处理(根据此highly voted SO answer)。由于我得到3个事件,他们应该按照适当的顺序执行,首先是“计算..”,更新屏幕,然后long_running以及所有这些,calculation done

那么为什么我会在执行long_running之前得到'计算完成'?

+0

你已经做了最接近的事情,javascript已经用'setTimeout'行来“产生一个新线程”。有人会很快提供更好的科学细节,但这个问题大约有100个重复。 – Jamiec

+0

@Jamiec 100重复?你能指出一个吗?我没有看到任何问题,询问为什么渲染事件优先于时间事件。 – daremkd

+0

我看过“为什么X会在Y之前发生”(其中Y是对'setTimeout'的调用)的次数是不可估量的。我现在要去狩猎他们,可惜不是! – Jamiec

回答

0

的点击回调的执行过程如下:

  1. $('#status_ok').text设置为'calculating....'
  2. setTimeout设置你作为一个参数传递后留出的时间是从执行它的功能。
  3. $('#status_ok').text设置为'calculation done'
  4. 当第二个传递,传递给setTimeout功能被执行

$('#status_ok').text('calculation done')应该是里面的setTimeout功能正常工作。

+0

这不是jQuery函数的工作方式。是的,DOM被更新,但是一个事件被分派给渲染器以显示更新的DOM。这不是一个操作。 – daremkd

+0

jQuery函数的工作方式与任何其他JS函数完全相同。试试这个简单的例子: '(function(){ console.log('First'); window.setTimeout(function(){console.log('Second');},1000); console.log 'Third'); })();' 输出将是'First,Third,Second'。 –