JavaScript原生缺乏同步阻塞的Sleep函数,导致异步计时期间后续代码仍会执行。本文介绍两种实现方式:一是利用for循环进行CPU轮询的简单方法,适合对精度要求不高的场景;二是基于事件队列和setTimeout的复杂方案,通过注册回调和索引管理实现更可控的暂停与恢复机制。
JavaScript同步阻塞Sleep函数的实现原理
由于JavaScript中的计时机制是异步的,在等待期间后续代码仍会继续执行,这往往不符合某些需要同步阻塞的场景。因此,开发者需要手动实现一个sleep()函数。尽管网上存在多种实现方案,但以下介绍的方法因其简单易懂且实用而被推荐分享。
基于轮询的简单Sleep实现
具体实现代码如下:
console.log('start...');
console.log('now time: ' + Date(/\d{10,10}/.exec(Date.now())));
function sleep(sleepTime) {
for(var start = Date.now(); Date.now() - start <= sleepTime; ) { }
}
sleep(5000); // sleep 5 seconds
console.log('end...');
console.log('end time: ' + Date(/\d{10,10}/.exec(Date.now())));
如果程序对sleep()函数的执行精度要求不高,这种基于循环轮询的方法是一个不错的选择。
基于事件队列的复杂Sleep方案
此外,还有一种更为复杂的实现方式,供有特定需求的读者参考:
具体代码如下:
function Sleep(obj,iMinSecond)
{
if (window.eventList==null)
window.eventList=new Array();
var ind=-1;
for (var i=0;i<window.eventList.length;i++)
{
if (window.eventList[i]==null)
{
window.eventList[i]=obj;
ind=i;
break;
}
}
if (ind==-1)
{
ind=window.eventList.length;
window.eventList[ind]=obj;
}
setTimeout("GoOn(" + ind + ")",iMinSecond);
}
function GoOn(ind)
{
var obj=window.eventList[ind];
window.eventList[ind]=null;
if (obj.NextStep) obj.NextStep();
else obj();
}
function Test()
{
alert("sleep");
Sleep(this,100);
this.NextStep=function()
{
alert("continue");
}
}