如何确保以指定的间隔精确调用setInterval的回调?

时间:2017-07-21 13:20:05

标签: javascript

以此功能为例:

function mySlowFunction(baseNumber) {
    console.time('mySlowFunction');
    var result = 0; 
    for (var i = Math.pow(baseNumber, 10); i >= 0; i--) {       
        result += Math.atan(i) * Math.tan(i);
    };
    console.timeEnd('mySlowFunction');
    return result;
}

这是一项非常耗费CPU的功能。 mySlowFunction(5)完成大约需要3秒钟。

现在考虑以下代码:

setInterval(() => console.log("interval"), 1000); 
mySlowFunction(5);

我希望它每秒记录一次“interval”,但是我知道由于mySlowFunction在线程上运行而JS是单线程的,setInterval的回调只在mySlowFunction之后执行1}}完成。

有什么方法可以确保在指定的时间间隔内调用回调?我想在基于浏览器的环境中使用它。

2 个答案:

答案 0 :(得分:1)

您不应期望在指定的延迟时间内开火 Here -> ( Reasons for delays longer than specified ) 有几个原因可能导致延误时间超过预期。无论如何,如果您仍想确保在mySlowFunction完成执行之前触发间隔,您可以按照评论中的提及使用Worker

  

Web Workers API的Worker接口代表了一个可以轻松创建的后台任务,可以将消息发送回其创建者。

mySlowFunction的计算分配给不同的线程。

以下是一个例子:

var blobWorker = URL.createObjectURL( new Blob([ '(',
    function() {
        self.onmessage = function(e) {
          
        	var result = 0; 
        	for (var i = Math.pow(e.data, 10); i >= 0; i--) {
            result += Math.atan(i) * Math.tan(i);
        	};
        	
          self.postMessage(result);
        };
    }.toString(),
')()' ], { type: 'application/javascript' } ) );

var worker = new Worker( blobWorker );

worker.onmessage = function(e) {

    console.log("result from mySlowWorker:", e.data);
}

var intervalId = setInterval(() => console.log("interval"), 1000);

worker.postMessage(5);

URL.revokeObjectURL( blobWorker );

setTimeout( _ => { clearInterval(intervalId); console.log('done') }, 5000)

答案 1 :(得分:0)

Javascript中无法保证定时器延迟。由于Javascript的单线程特性,一次一个地执行一个异步事件,如定时器和鼠标点击。