How do I pause execution in JavaScript?
2006-04-12 14:21
561 查看
http://www.faqts.com/knowledge_base/view.phtml/aid/1602Is there a wait statement in JavaScript?Is there a sleep method to pause execution?Is there a sleep method to pause execution?setTimeout does not work well when called recursively in NN 6.0. Works fine with IE 5.0 and aboveMay 18th, 2002 20:20
Daniel LaLiberte, Brent Boyer, Martin Honnen, mercury rising,
Daniel LaLiberte, Brent Boyer, Martin Honnen, mercury rising,
There is no true wait, sleep, or similar function in either the core JavaScript language or in client side JavaScript. Client side JavaScript however provides setTimeout('js code here', delayInMilliseconds) which allows you to schedule execution of piece of script and setInterval('js code here', intervalInMilliseconds) which allows you to periodically excute a piece of script. So if you wanted (pseudo code) statement1; wait (someDelay); statement2; you would stuff the code into functions function statement1 () { // your code here } function statement2 () { // your code here } and call statement1(); setTimeout('statement2()', someDelay); If you wanted (pseudo code) while (someCondition) { statement1; wait (someDelay) } you code var tid; function statement1 () { // your code here if (!condition) clearInterval(tid); } tid = setInterval('statement1()', someDelay); Note that both setInterval and setTimeout return a timer id you can use to clear the scheduled execution e.g. var tid = setTimeout('js code here', delayInMilliseconds); ... clearTimeout(tid); respectively var tid = setInterval('js code here', delayInMilliseconds); ... clearInterval(tid); There are some major limitations with the solution given above. First, it makes your code more awkward to write and difficult to read. Even worse, the above technique will not work at all for certain situations. For instance, consider a function that has state (i.e. local variables): it may be impossible to split it apart into 2 functions as called for above, since each half may need access to the full state. (It may be impossible to store the state in global variables instead of locals --say, if you are using the function recursively. Also, you cannot pass the state as args to the second function via setTimeout/setInterval because those functions only take Strings as the function specification.) Below is a Javascript function that (from the callers perspective) is in fact a true pause: /* * This function will not return until (at least) * the specified number of milliseconds have passed. * It does a busy-wait loop. */ function pause(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } } The main problem with this function is that it is not sleeping the underlying Javascript interpreter thread. Instead, it is worthlessly burning up a lot of CPU cycles. If you have a modern multithreaded browser, other processes (e.g. loading of a webpage) should still take place in other threads, but they will not finish as fast as they ought. A sneaky way to get the effect of a true pause while not burning CPU cycles is to use a modal dialog with a timeout that closes the modal dialog window and resumes execution. A modal dialog pauses execution in the code that created it, but allows other threads to continue. /* * This function will not return until (at least) * the specified number of milliseconds have passed. * It uses a modal dialog. */ function pause(numberMillis) { var dialogScript = 'window.setTimeout(' + ' function () { window.close(); }, ' + numberMillis + ');'; var result = // For IE5. window.showModalDialog( 'javascript:document.writeln(' + '"<script>' + dialogScript + '<' + '/script>")'); /* For NN6, but it requires a trusted script. openDialog( 'javascript:document.writeln(' + '"<script>' + dialogScript + '<' + '/script>"', 'pauseDialog', 'modal=1,width=10,height=10'); */ } If you want a true and CPU efficient pause, you will need to use a real language. Your best choice is Java. Client side JavaScript in NN4+ has direct access to Java objects via NN's LiveConnect technology, so your Javascript can simply call java.lang.Thread.sleep(timeInMilliSeconds) CAUTION: if the JVM (Java Virtual Machine) has not yet started, there is an additional (several second) JVM start delay before your sleep call is executed. Subsequent calls will then delay the correct amount. Officially, IE does not support Liveconnect. So, if you want a reliable cross browser solution, you can simply embed the above in a public method of a Java applet as follows: /** * Simply calls <code>Thread.sleep( (long) timeInMillis )</code>. * <p> * This method is needed because Javascript has no sleep * functionality. Also, the argument must be a float * because that is what Javascript's Number type is * automaticly converted to when it calls this method. * <p> * @see <a href="http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/livec on.htm#1007805">Data type conversion</a> */ public void sleep(float timeInMillis) throws InterruptedException { Thread.sleep( (long) timeInMillis ); } If the above is a member of the first Java applet in your html file, you may then invoke it from your Javascript like window.document.applets[0].sleep(2*1000); // sleep for 2 seconds WARNING: you should verify whether or not the browser you want to work in is actually intelligently multithreaded (i.e. runs the Javascript interpreter in it's own thread). A way that you can simply test this is to write a very large loop that doesn't do much and see whether or not the browser can still do things like respond to its GUI. Using this technique, it has been reported that NN appears to run the JS interpreter in the same thread as the browser gui.
相关文章推荐
- How do I pause all animations in a layer tree?
- How do I remove a particular element from an array in JavaScript?
- How do I get the name of an object's type in JavaScript
- How do I debug JavaScript in Safari?
- How do you check if a variable is an array in JavaScript? [duplicate]
- How do I add capabilities to my executable in qt for symbian?
- How do I use Cygwin in Geophysics ?
- How to enable javascript in windows server 2008 R2 enterprise
- How do I list the files in a directory?
- How do I add classes to main menu ul and li in Drupal 8
- JQuery怎么知道一个元素是否隐藏或显示How do you test if something is hidden in jQuery?
- How to include JavaScript file in JSF
- How do I use Tasker to run a sync in FolderSync?
- How do you set, clear and toggle a single bit in C?
- How Does Closure Work in Javascript?
- How Do I Declare A Block in Objective-C? [备忘]
- In Javascript Class, how to call the prototype method.(three method)
- In Javascript Class, how to call the prototype method.(three method)
- mac如何关闭gradle的task,杀死gradle进程 how-to-stop-gradle-task-execution-in-Android-studio
- How to run eclipse in clean mode? and what happens if we do so?