JS에는 수면 메소드가 내장되어 있지 않습니다. 수면을 원할 경우 메소드를 직접 정의해야 합니다.
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, 코드는 다음과 같습니다.
이 구문은 더욱 무섭고, Java에서는 권장하지 않는 스레드 메소드 이름이기도 합니다. 솔직히 말해서 저는 Narrative JS를 더 선호합니다.
Narrative JS와 마찬가지로 jwacs도 사전 컴파일이 필요하며 사전 컴파일러는 LISP 언어로 작성됩니다. 현재 알파 버전이기도 합니다. 두 가지에 대한 자세한 소개 및 비교는 SitePoint의 새 기사: 전처리를 통한 비동기 Javascript 콜백 제거
를 참조하세요.복잡한 JavaScript 스크립트를 작성할 때 때로는 Java의 Thread.sleep 또는 sh 스크립트의 sleep 명령을 통해 달성되는 효과와 유사하게 스크립트가 지정된 시간 동안 정지되어야 하는 경우가 있습니다.
우리 모두 알고 있듯이 JavaScript는 Java와 유사한 스레드 제어 기능을 제공하지 않습니다. setTimeout과 setInterval이라는 두 가지 타이밍 실행 제어 기능이 있지만 모든 요구 사항을 충족할 수는 없습니다. 오랫동안 많은 사람들이 JavaScript에서 절전/일시 중지/대기를 구현하는 방법을 문의해 왔으며 실제로 몇 가지 형편없는 해결책이 있습니다.
가장 간단하고 최악의 방법은 루프를 작성하는 것입니다. 코드는 다음과 같습니다.
위 코드는 실제로 스크립트 해석기를 절전 모드로 전환시키지는 않지만 CPU를 빠르게 높은 부하에 빠뜨리는 부작용이 있습니다. 브라우저는 해당 기간 동안 정지된 애니메이션 상태로 정지될 수도 있습니다.
둘째, IE의 특별한 대화 상자 구현을 사용하여 전 세계의 길을 찾는 똑똑한 사람들이 있습니다.
말할 필요도 없이 IE에서만 지원된다는 단점이 있습니다(IE7은 보안 제한으로 인해 목적을 달성할 수 없습니다).
위의 방법 외에도 Applet을 사용하거나 Windows Script Host의 WScript.Sleep()을 호출하는 등의 기발한 아이디어도 있습니다.
마지막으로, 더 똑똑한 사람들이 최고의 솔루션을 개발했습니다. 먼저 코드를 살펴보겠습니다.
예, ->()와 같은 구문을 보는 것은 Prototype의 $() 함수를 보는 것만큼이나 충격적입니다. 그러나 이 스크립트는 브라우저에서 직접 구문 오류를 보고합니다. 실제로 클라이언트 브라우저가 인식하는 JavaScript로 사전 컴파일되어야 합니다. 컴파일된 스크립트는 다음과 같습니다.
我看不懂,也不想去看懂了。这些工作全部会由 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>