您的位置:首页 > Web前端 > JavaScript

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,

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: