2016-08-10 76 views
0

我想监视一个for循环每X毫秒的内容:如何监控for-loop?

下面是一个例子,我希望看到进展的百分比每0.1秒时:

for (i = 0, max = 9007199254740992, timer = setInterval(function() {console.log(100*i/max);}, 100); i < max; i++) { 
    // something 
} 
clearInterval(timer); 

但它没有做任何输出。

我不想在我的循环中添加一个测试,以避免使用无用的计算时间。

+2

For循环将在100ms内完成 –

+0

@RajaprabhuAravindasamy - 我完全没有做循环,但'循环中'初始化' – Rayon

+1

''setInterval'的回调函数将在'duration'后被调用,如显式调用'clearInterval'在'100ms'之前调用,''callback'永远不会被调用。 – Rayon

回答

6

由于Javascript的单线程特性,无论执行多长时间,您的setInterval()回调都不可能在for循环结束之前调用。

我建议以相反的方式来做:每N次迭代记录已用时间。

var res = [], 
 
    ts = performance.now(); 
 

 
for(var i = 0, max = 1E6; i < max; i++) { 
 
    if(!(i % 10000)) { 
 
    res.push(performance.now() - ts); 
 
    } 
 
    // do something 
 
} 
 

 
console.log(res);

或者:

var res = [], 
 
    ts = performance.now(); 
 

 
for(var i = 0, iMax = 1E6; i < iMax; i += 10000) { 
 
    for(var j = i, jMax = Math.min(i + 10000, iMax); j < jMax; j++) { 
 
    // do something 
 
    } 
 
    res.push(performance.now() - ts); 
 
} 
 

 
console.log(res);

如果你真的想登录实时,你必须得到控制后,各浏览器一批N次迭代。性能方面,这可能会产生重大影响。

var res = [], 
 
    ts = performance.now(); 
 

 
function processBatch(i, iMax, sz) { 
 
    for(var j = i, jMax = Math.min(i + sz, iMax); j < jMax; j++) { 
 
    // do something 
 
    } 
 
    console.log((j * 100/iMax) + '%', (performance.now() - ts).toFixed(2) + 'ms'); 
 

 
    if(j < iMax) { 
 
    setTimeout(function() { processBatch(j, iMax, sz); }, 0); 
 
    } 
 
} 
 

 
processBatch(0, 1E6, 10000);

编辑:这第三种方法显著更新。以前的版本是错误的。

+1

你对它未被调用的原因是正确的,但OP表示他们不想在循环中做一个测试“以避免使用无用的计算时间”。也许在外循环中使用嵌套循环?或者网络工作者(虽然看起来过于复杂)? – samgak

+1

@samgak你说得对。但是,任何措施都会改变结果。不过,我已经添加了一个备用方法。 – Arnauld

+1

如果(!(i&mask)){与%8192相同,则可以通过使用位掩码获得比模数更便宜的方式:'mask =(1 << 13)-1''缺点:你必须坚持2的幂。如果'max%10000!= 0'更好,你的第二次尝试将会过冲,因为(var i = 0,max = 1E6; i Thomas