This question already has answers here:
setInterval timing slowly drifts away from staying accurate
                            
                                (4个答案)
                            
                    
                    
                        How to create an accurate timer in javascript?
                            
                                (8个答案)
                            
                    
                2年前关闭。
        

    

以这个功能为例:

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);


我希望它每秒记录一次“间隔”,但是我知道由于mySlowFunction在线程上运行并且JS是单线程的,因此setInterval的回调仅在mySlowFunction完成后才执行。

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

最佳答案

您不应期望间隔会在指定的延迟后触发。
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)

09-12 08:35