js中自定义方法实现停留几秒sleep


Posted in Javascript onJuly 11, 2014

js中不存在自带的sleep方法,要想休眠要自己定义个方法

function sleep(numberMillis) { 
var now = new Date(); 
var exitTime = now.getTime() + numberMillis; 
while (true) { 
now = new Date(); 
if (now.getTime() > exitTime) 
return; 
} 
}

以下是补充:

除了Narrative JS,jwacs(Javascript With Advanced Continuation Support) 也致力于通过扩展JavaScript语法来避免编写让人头痛的异步调用的回调函数。用jwacs 实现的sleep,代码是这样:

function sleep(msec) {

    var k = function_continuation;

    setTimeout(function() { resume k <- mesc; }, msec);

    suspend;

}

这个语法更吓人了,而且还是java里不被推荐使用的线程方法名。坦白说我倾向于 Narrative JS。

同Narrative JS一样,jwacs也需要预编译,预编译器是用 LISP 语言编写。目前也是 Alpha 的版本。两者的更多介绍和比较可以参阅 SitePoint 上的新文章: Eliminating async Javascript callbacks by preprocessing

编写复杂的JavaScript脚本时,有时会有需求希望脚本能停滞指定的一段时间,类似于 java 中的 Thread.sleep 或者 sh 脚本中的 sleep 命令所实现的效果。

众所周知,JavaScript 并没有提供类似于 Java 的线程控制的功能, 虽然有 setTimeout 和 setInterval 两个方法可以做一些定时执行控制,但并不能满足所有的要求。一直以来,都有很多人问如何在JavaScript中实现 sleep/pause/wait ,也确实有些很蹩脚的解决方案:

最简单也最糟糕的方法就是写一个循环,代码可能如下:

function sleep(numberMillis) {

    var now = new Date();

    var exitTime = now.getTime() + numberMillis;

    while (true) {

        now = new Date();

        if (now.getTime() > exitTime)

            return;

    }

}

如上的代码其实并没有让脚本解释器sleep下来,而且有让CPU迅速上到高负荷的附作用。浏览器甚至会在该段时间内处于假死状态。

其二有聪明人利用IE特殊的对话框实现来曲径通幽,代码可能如下:

function sleep(timeout) {

 window.showModalDialog("javascript:document.writeln('<script>window.setTimeout(function () { window.close(); }, " + timeout + ");<\/script>');");

}window.alert("before sleep ...");

sleep(2000);

window.alert("after sleep ...");

缺点不用多说,只有IE支持(IE7因为安全限制也而不能达到目的)。

除上之外,还有利用Applet或者调用Windows Script Host的WScript.Sleep()等等鬼点子,这些都是万不得已的权宜之计。

终于有了更聪明的人,开发出了也许是最佳的方案,先看代码:

function sleep(millis) {

    var notifier = NjsRuntime.createNotifier();

    setTimeout(notifier, millis);

    notifier.wait->();

}

没错,看到 ->() 这样的语法,就象刚看到Prototype的 $() 函数一样让我惊为天人。不过直接在浏览器中这段脚本是会报告语法错误的。实际上它们需要经过预编译成客户端浏览器认可的JavaScript。编译后的脚本如下:

function sleep(millis){

var njf1 = njen(this,arguments,"millis");

nj:while(1) {

try{switch(njf1.cp) { 

case 0:njf1._notifier=NjsRuntime.createNotifier();

setTimeout(njf1._notifier,njf1._millis);

njf1.cp = 1;

njf1._notifier.wait(njf1);

return;

case 1:break nj;

}} catch(ex) { 

if(!njf1.except(ex,1)) 

return; 

}} 

njf1.pf();

}

我看不懂,也不想去看懂了。这些工作全部会由 Narrative JavaScript ———— 一个提供异步阻塞功能的JS扩展帮我们实现。我们只需要编写之前那个怪异的 ->() 语法, 然后通过后台预先静态编译或者前台动态编译后执行就可以实现 sleep 的效果。
Narrative JavaScript 宣称可以让你从头昏眼花的回调函数中解脱出来,编写清晰的Long Running Tasks。目前还是 alpha 的版本,在 Example 页面上有一个移动的按钮的范例。首页上也提供了源码下载。以我薄弱的基础知识,我只能勉强的看出代码中模拟了状态机的实现,希望有精通算法的朋友能为我们解析。
最后,还是我一直以来的观点: 除非很必要,否则请保持JavaScript的简单。在JavaScript 能提供原生的线程支持之前,或许我们可以改变设计以避免异步阻塞的应用。

有bug的曲折实现

<script type"text/javascript">
/*Javascript中暂停功能的实现
Javascript本身没有暂停功能(sleep不能使用)同时 vbscript也不能使用doEvents,故编写此函数实现此功能。
javascript作为弱对象语言,一个函数也可以作为一个对象使用。
比如:

[code]
function Test(){
 alert("hellow");
 this.NextStep=function(){
 alert("NextStep");
 }
}
我们可以这样调用 var myTest=new Test();myTest.NextStep();
我们做暂停的时候可以吧一个函数分为两部分,暂停操作前的不变,把要在暂停后执行的代码放在this.NextStep中。
为了控制暂停和继续,我们需要编写两个函数来分别实现暂停和继续功能。
暂停函数如下:
*/
function Pause(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 + ")",1000);
}
/*
该函数把要暂停的函数放到数组window.eventList里,同时通过setTimeout来调用继续函数。
继续函数如下:
*/

function GoOn(ind){
 var obj=window.eventList[ind];
 window.eventList[ind]=null;
 if (obj.NextStep) obj.NextStep();
 else obj();
}
/*
该函数调用被暂停的函数的NextStep方法,如果没有这个方法则重新调用该函数。
函数编写完毕,我们可以作如下册是:
*/
function Test(){
 alert("hellow");
 Pause(this,1000);//调用暂停函数
 this.NextStep=function(){
 alert("NextStep");
 }
}
</script>
Javascript 相关文章推荐
通过js脚本复制网页上的一个表格的不错实现方法
Dec 29 Javascript
几行代码轻松搞定jquery实现flash8类似的连接效果
May 03 Javascript
JavaScript CSS菜单功能 改进版
Dec 20 Javascript
DWZ table的原生分页浅谈
Mar 01 Javascript
jQuery bxCarousel实现图片滚动切换效果示例代码
May 15 Javascript
jquery实现网页查找功能示例分享
Feb 12 Javascript
我的Node.js学习之路(一)
Jul 06 Javascript
12个非常实用的JavaScript小技巧【推荐】
May 18 Javascript
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
Aug 30 Javascript
JavaScript遍历查找数组中最大值与最小值的方法示例
May 24 Javascript
详解JVM系列之内存模型
Jun 10 Javascript
Echarts如何重新渲染实例详解
May 30 Javascript
使用jquery prev()方法找到同级的前一个元素
Jul 11 #Javascript
让checkbox不选中即将选中的checkbox不选中
Jul 11 #Javascript
常用jQuery选择器总结
Jul 11 #Javascript
基于jQuery的图片不完全按比例自动缩小
Jul 11 #Javascript
js动态改变select选择变更option的index值示例
Jul 10 #Javascript
javascript event在FF和IE的兼容传参心得(绝对好用)
Jul 10 #Javascript
js确认删除对话框适用于a标签及submit
Jul 10 #Javascript
You might like
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
2013/06/18 PHP
PHP小白必须要知道的php基础知识(超实用)
2017/10/10 PHP
用javascript实现读取txt文档的脚本
2007/07/20 Javascript
JavaScript中几种常见排序算法小结
2011/02/22 Javascript
jquery实现非叠加式的搜索框提示效果
2014/01/07 Javascript
用JS在浏览器中创建下载文件
2014/03/05 Javascript
JavaScript实现的in_array函数
2014/08/27 Javascript
基于jquery固定于顶部的导航响应浏览器滚动条事件
2014/11/02 Javascript
使用 js+正则表达式为关键词添加链接
2014/11/11 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
6种javascript显示当前系统时间代码
2015/12/01 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
关于jQuery里prev()的简单操作代码
2017/10/27 jQuery
Vue入门之animate过渡动画效果
2018/04/08 Javascript
JavaScript 扩展运算符用法实例小结【基于ES6】
2019/06/17 Javascript
VUE前后端学习tab写法实例
2019/08/06 Javascript
vue 需求 data中的数据之间的调用操作
2020/08/05 Javascript
[02:07]TI9显影之尘系列 - Vici Gaming
2019/08/20 DOTA
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
跟老齐学Python之开始真正编程
2014/09/12 Python
Python中的defaultdict与__missing__()使用介绍
2018/02/03 Python
Python实现将数据写入netCDF4中的方法示例
2018/08/30 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
简单了解python gevent 协程使用及作用
2019/07/22 Python
基于CentOS搭建Python Django环境过程解析
2020/08/24 Python
施华洛世奇匈牙利官网:SWAROVSKI匈牙利
2019/07/06 全球购物
当文件系统受到破坏时,如何检查和修复系统?
2012/03/09 面试题
2014年入党积极分子学习三中全会思想汇报
2014/09/13 职场文书
2014和解协议书范文
2014/09/15 职场文书
事业单位年度考核评语
2014/12/31 职场文书
Nginx的反向代理实例详解
2021/03/31 Servers
Vue项目中如何封装axios(统一管理http请求)
2021/05/02 Vue.js
Spring Cloud Netflix 套件中的负载均衡组件 Ribbon
2022/04/13 Java/Android