JS中怎么实现sleep的功能

JavaScript047

JS中怎么实现sleep的功能,第1张

1. jquery的$.delay()方法

设置一个延时来推迟执行队列中之后的项目。这个方法不能取代JS原生的setTimeout。

The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.

例子:在.slideUp() 和 .fadeIn()之间延时800毫秒。

HTML 代码:

<div id="foo /">

jQuery 代码:

$('#foo').slideUp(300).delay(800).fadeIn(400)

2. 通过循环消耗cpu

function sleep(n) {

var start = new Date().getTime()

while(true) if(new Date().getTime()-start >n) break

}

3. 用setTimeout。

假设有三个步骤,步骤之间需要暂停一段时间;可以采用如下的方法:

function firstStep() {

//do something

setTimeout("secondStep()", 1000)

}

function secondStep() {

//do something

setTimeout("thirdStep()", 1000)

}

function thirdStep() {

//do something

}

JavaScript中是没有sleep命令的,通常情况下,可以使用现有的setTimeout(),clearTimeout()和setInterval()来完成,在这种情况下,你应该使用内置函数。但如果你真的需要有选项的sleep或等待语句,看看什么代码可以工作得最好。

sleep方法有什么要求呢?看看下面的权威描述最能说明问题:

暂停应用程序的当前线程,时间为指定的毫秒数,允许其他进程(或线程)继续运行。

 

下面是javascript实现sleep函数的各种方法:

(1)通过循环实现JavaScript sleep

(2)通过Java Applet实现JavaScript sleep

(3)通过Flash实现JavaScript sleep

(4)通过XMLHttp实现JavaScript sleep

 

通过循环实现JavaScript sleep

代码如下:

<script type="text/javascript">

// bad implementation

function sleep(milliSeconds){    

    var startTime = new Date().getTime()  // get the current time   

    while (new Date().getTime() < startTime + milliSeconds)  // hog cpu

    }

 </script>    

我们使用一个while循环,在第3行,不断检测当前的时间,到时间了我们就停止循环。这个循环运行速度很快,浏览器将占用所有宝贵的CPU资源。检查时间可能看起来并不多,但每秒做数千次(或几万),使您的计算机上性能受到影响。

通过Java Applet实现JavaScript sleep

这个解决方案是插入一个Java Applet,通过Javascript和java applets进行通讯,Java Applets使用Java的Thread.sleep()方法休眠线程(不占用资源)。

<applet code="DevCheater.class" name="devCheater" id="devCheater" mayscript="true" height="1" width="1">

</applet> 

<script type="text/javascript">     

    function sleep(milliSeconds){        

    // runs Java Applets sleep method        

    document.devCheater.sleep(milliSeconds)     

    } 

</script>    

此方法不冻结所有页面中的其他javascript(使用Chrome时除外)。不幸的是,它需要安装一个Java插件。

通过Flash实现JavaScript sleep

如果我们尝试了Java,为什么不试试ADOBE FLASH。我创建了一个Flash应用程序,有一个方法叫flashSleep()。我使用javascript调用我的flash方法,并传入需要sleep的毫秒数。但不幸的是,这种方法在大多数的浏览器中也导致了阻塞。

<script type="text/javascript">     

    function sleep(milliSeconds){        

        // call sleep method in flash        

        getFlashMovie("flashSleep").flashSleep(milliSeconds)    

    }     

    function getFlashMovie(movieName){        

    // source: http://kb2.adobe.com/cps/156/tn_15683.html        

    var isIE = navigator.appName.indexOf("Microsoft") != -1        

    return (isIE) ? window[movieName] : document[movieName]    

    } 

 </script>    

  <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="50" height="50" id="flashSleep" align="middle">

  <param name="allowScriptAccess" value="sameDomain" />

  <param name="allowFullScreen" value="false" />

  <param name="movie" value="flashSleep.swf" />

  <param name="quality" value="high" /><param name="bgcolor" value="#ffffff" />  <embed src="flashSleep.swf" quality="high" bgcolor="#ffffff" width="50" height="50" name="flashSleep" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />

  </object>    

测试发现,Flash也不是理想的方式。

通过XMLHttp实现JavaScript sleep

另一种方法是使用XMLHttp进行服务器通信。

<script type="text/javascript"> 

    function sleep(milliSeconds){    

        var resource    

        var response    

        if(typeof ActiveXObject == 'undefined'){        

            resource = new XMLHttpRequest()    

        }    

        else{        

            // IE        

            resource = new ActiveXObject("Microsoft.XMLHTTP")    

       }     

       try{        

           resource.open('GET', 'sleep.php?milliSeconds=' + milliSeconds, false)        

           resource.send(null)        

           response = resource.responseText // JavaScript waits for response            }catch(e){        

               alert(e)    

          }         

          return true}     

 </script>    

 <?PHP    

     $milliSeconds = intval($_REQUEST['milliSeconds'])    

     if($milliSeconds > 60*1000){        

         // limit server abuse       

          $milliSeconds = 10    

     }         

    usleep($milliSeconds * 1000) // note: usleep is in micro seconds not milli    echo "done"

?>    

该方法并不占用用户计算机的CPU资源,但加重了服务器额外的负载。而且该方法阻塞了浏览器中其它javascript,对于服务器来说产生了类似DDos的攻击。

结论

从测试数据来看,许多的实现都有一定的副作用,所以setTimeout()或setInterval()函数还是最好的选择。

let array = [[{'level':"赛程表1",'time':3000},{'level':"对阵图1",'time':8000},{'level':"小组积分赛1",'time':10000}],[{'level':"赛程表2",'time':5000},{'level':"对阵图2",'time':8000},{'level':"小组积分赛2",'time':10000}],[{'level':"赛程表3",'time':5000},{'level':"对阵图3",'time':6000},{'level':"小组积分赛3",'time':9000}]]

async function sleep(time) {

  await new Promise((resolve,reject)=>{

     setTimeout(() => {

      //  console.log(`等了${time}s`)

       resolve()

     }, time)

  })

}

async function doSome(params) {

  for (let x = 0 x < array.length x++) {

    const eleArr = array[x]

    for (let y = 0 y < eleArr.length y++) {

      const ele = eleArr[y]

      console.log(ele.level)

      await sleep(ele.time)

      if (x>=array.length-1 && y>=eleArr.length-1) {

        doSome()

      }

    }

  }

}

doSome()