JavaScript sleep
Delay for a given number of seconds
1 2 3 4 56 7 8 9 1011 12 13 14 1516 | function sleep (seconds) { // Delay for a given number of seconds // // version: 1008.1718 // discuss at: http://phpjs.org/functions/sleep // + original by: Christian Doebler // + bugfixed by: Brett Zamir (http://brett-zamir.me) // % note: For study purposes. Current implementation could lock up the user's browser. // % note: Consider using setTimeout() instead. // * example 1: sleep(1); // * returns 1: 0 var start = new Date().getTime(); while (new Date() < start + seconds*1000) {} return 0;} |
Examples
Running
1 | sleep(1); |
Should return
1 |
Dependencies
No dependencies, you can use this function standalone.
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have sleep goodness in JavaScript.
You can see a few different implementations of sleep in JavaScript at the following site. They all end up the same way though... freezing the browser.
http://www.devcheater.com - javascript sleep
@ Arun Gautam: It also says in the function notes that "For study purposes. Current implementation could lock up the user's browser. " so this is expected behavior.
Since this function follows the PHP API, it takes the argument in seconds. So, it intentionally does lock up the browser for the given number of seconds. If the seconds amount is small enough, it won't loop so much (say if you put it as a fraction of a second).
@ Brett Zamir: Wow, you even formatted them so that they can go straight into SVN. Thanks a lot dude!
Come to think of it, there should probably be a warning with time_sleep_until() noting that the timestamp is PHP-style (in seconds) as opposed to JavaScript style (in milliseconds), so they should NOT pass in a Date object because that is in milliseconds, while this PHP function expects the timestamp in seconds, as is conventional in PHP.
Missed another easy one:
[CODE="Javascript"]
// Note that this function's argument, contrary to the PHP name, does not start being significant until 1,000 microseconds (1 millisecond)
function usleep(microseconds) {
// http://kevin.vanzonneveld.net
// % note: For study purposes. Current implementation could lock up the user's browser.
// % note: Consider using setTimeout() instead.
// * example 1: usleep(2000000); // delays for 2 seconds
// * returns 1: true
var start = new Date().getTime();
while (new Date() < (start + microseconds/1000));
return true;
}
[/CODE]
Whoops...Missed the two forward slashes for the comment on the line:
[CODE="Javascript"] * example 1: time_sleep_until(1233146501) // delays until the time indicated by the given timestamp is reached
[/CODE]
Hi,
I know I need to get back to you on gettype, but here are two more functions (feel free to send me the SVN details if you want me to post them there instead)...
[CODE="Javascript"]
function time_sleep_until(timestamp) {
// http://kevin.vanzonneveld.net
// % note: For study purposes. Current implementation could lock up the user's browser.
// % note: Consider using setTimeout() instead.
* example 1: time_sleep_until(1233146501) // delays until the time indicated by the given timestamp is reached
// * returns 1: true
while (new Date() < timestamp*1000);
return true;
}
// Note that the following function's argument, contrary to the reference to nanoseconds, does not start being significant until 1,000,000 nanoseconds (milliseconds), since that is the smallest unit handled by JavaScript's Date function.
function time_nanosleep(seconds, nanosecs) {
// http://kevin.vanzonneveld.net
// % note: For study purposes. Current implementation could lock up the user's browser.
// % note: Consider using setTimeout() instead.
// * example 1: time_nanosleep(1, 2000000000); // delays for 3 seconds
// * returns 1: true
var start = new Date().getTime();
while (new Date() < (start + seconds*1000+nanosecs/1000000));
return true;
}
[/CODE]
Actually, it's not a bug (though changing it doesn't hurt and may be good practice). Only array (or object) _contents_ are passed in by reference. The array or object itself is not, so (as in the defined() function) we're ok manipulating the argument. That's probably the most confusing thing about JavaScript, especially coming from a PHP background. But it doesn't hurt to be changed, and again, it might be seen as good practice.
@ Brett Zamir & Onno Marsman: That bug made me think: We have to be carefull when we do this kind of input sanitization:
[CODE="Javascript"]
function convert(a, b) {
a = a + '';
b = b + '';
}
[/CODE]
When people accidentally pass an array to a function that: they end up with a string. Totally unexpected & unwanted behavior.
This actually does have its uses... Sometimes one needs a small delay in which nothing can go on...
This can be simplified slightly as follows:
[CODE="Javascript"]function sleep(seconds) {
// http://kevin.vanzonneveld.net
// + original by: Christian Doebler
// % note: For study purposes. Current implementation could lock up the user's browser.
// % note: Consider using setTimeout() instead.
// * example 1: sleep(1);
// * returns 0
var start = new Date().getTime();
while (new Date() < start + seconds*1000);
return 0;
}[/CODE]
Date() is auto-converted in this situation and increasing the seconds on its own assignment line (without naming it ms, etc.) makes it look like we are increasing the delay by 1000! :)
The statement Return should always be 0 in the case of this function in JS (since JS shouldn't have any error), so I changed that line in the notes.
@ Onno Marsman: No need to guess the category. We copy the PHP categories. So that also meanns functions can't belong to two categories. We switched to that structure because the giant list of files became too hard to maintain. Also, some devs had more affinity with certain categories (like you with math maybe?) and this made it easier for them to contribute.
K, nice.
Isn't it a good idea then to discard the directory structure with Math and Strings etc. altogether? Sometimes it's a pain to guess the directory a function is in.
Maybe something could be added to the comments to define in which "category" a function should be in. That way a function could be in multiple categories.
@ Onno Marsman: The compile tool will have popular (or predefined) profiles. Selecting these from a selectbox will automatically check all associated functions & their dependencies.
We're serializing, hasing, & saving the choices, which will give us insight in popular choices. Popular choices can also have titles like: 'minimal', 'math', etc.
This way we do not have exclusive relations between functions & categories, and php.js source will be seperated from implementation. This would make it easier to maintain (no need for 12 directories with each a math, strings, network, etc dir)
Maybe it (and others like it) should be in a separate section called "unwise" (or something more subtle), not to be included in the main download. This makes it possible to implement other functions that must use sjax without encouraging their usage. For "sleep" (to stay on topic) this is also an excellent place to reside.
I have thought of even more sections that would result in different flavors of php.js, but it might be hard to maintain. Examples:
- Functions that are really missing in JS (addslashes etc.)
- Functions that add extra php-like behavior (count, several array functions, min, max, etc. )
- Functions that are just wrappers for js-functions (tan, cos, pi, etc.)
It's just an idea. I guess it's difficult to place every function in one of these sections and there might even be functions that should have different implementations for different sections ;)
@ Onno Marsman: A serverside component lays not within my ambitions for the php.js project this has been decided by the core team a long time ago as well so we're on the same page, no misunderstanding about that.
You have compelling points against sjax. And I'm okay with moving all functions that would require that to _notporting.
I still think we should keep file_get_contents in for study purposes though. Adding additional warnings to the function's comments should help people make better judgment (these 'notes' will have a more dominant place on the new site).
Another reason for keeping file_get_contents is that it has triggered a lot of enthusiasm and people to think about what we're doing here.
I would aim for "no reason at all". Although we're mimicking PHP, we shouldn't use it. It's still a javascript library which could theoretically be used in conjunction with any type of server-side language or even none at all.
Any problems we would solve in this context we as programmers should actually solve server-side instead of client-side to prevent serious security or performance issues. Having said this, even the existence of the function file_get_contents could be debatable.
SJAX is fun to use, but is not practical at all, because, as I understand, it locks the browser. There is always the other better solution: AJAX, which requires us to use events instead of the iterative approach we're used to in PHP. So be it... We shouldn't encourage people to use the wrong approach. Of course this whole library has "performance issues" written all over it, but we're crossing a line when we start to make architectural decisions in a part of an application that isn't meant for it.
So my vote would be to never use SJAX and even move file_get_contents to the notporting directory. I must say though that I am very tempted to use file_get_contents, and I guess that is exactly the problem I have with it.
@ Philip Peterson & Onno Marsman: I've made a start with moving function to http://trac.phpjs.org/projects/phpjs/browser/trunk/_notporting
It's a very rough begin, if you want, please make changes in SVN or comment on it. Note that I left some 'file-reading' functions in there, because I see some possibilities for SJAX (not A-jax ;) there just like we do with file_get_contents.
One might also argue that we could implement the entire PHP language by providing serverside script that forwards mysql_query calls. That would however be very slow, insecure and a bad idea. Maybe the future will provide better means or no reason at all to do this.
Let's hear your thoughts.
@ Philip & Onno: But it might cause unexpected results. I would rather have people investigate in other options (throwing errors, have their functions return false to let the caller know to stop executing) than offer them exit. It's radical, but beginners might not be able to judge that. Making us responsible in some way.
About the _unported vs ported functions.. I think we should have another directory in SVN: _notporting or something like that, and move 'crazy' php functions that are currently in _unported over there.
Core members will know what not to port, and we have a better idea of how complete the project already is.
Furthermore, this directory could be indexed to generate a list over at the new phpjs.org site, making it clear to non-svn-nor-core-developers where we stand.
True, true, but theoretically there _could_ be an exit() function that resembles PHP's behavior, is my point. The only issue would be one of "morality" I suppose, since it would involve clearing out all the contents of SCRIPT tags, and possibly some of stylesheets and attributes, but this would not in most cases affect the end user.
I was of course just joking when I talked about phpinfo() and such. Nobody should ever want to do this in any serious way.
My opinion is that functions like sleep or exit should not be implemented because they won't do anything that even resembles phps behaviour. To avoid people submitting these functions or asking questions about them , I suggest keeping an empty function in the library and at least some comments to put people in the right direction. An error message prevents questions from people that just don't take the time to look into the code, and saves everybody else the trouble.
Haha, I've thought of that, and it might actually be fun, but the unfortunate and obvious problem is a) the bulk and b) the non-applicability of SO many of those things to javascript. (think of the bulk of storing those images, too!)
Well, I personally think sleep is actually more of an impractical thing than my proposed exit() function, as sleep can actually be abused and break a very good number of browsers (especially if the argument is set to Infinity). I do think sleep() is good to have for small amounts of time, but it serves nearly no practical purpose, other than calculating the date a lot of times.
Currently exit() does nothing but the equivalent of clicking the stop button, and theoretically it could put a halt to virtually all javascript activity (remove the script tags and onaction attributes of document objects), which may be very useful in things such as game development.
How about something like:
[CODE="Javascript"]
function sleep()
{
throw new Error('Function sleep: no javascript equivalent possible. Please use a construct with javascripts setTimeout instead');
}
[/CODE]
This won't be very useful for experienced users, but code like this could be helpful for people trying to teach themselves javascript from PHP, which, I think, is also a purpose for this library. Maybe we can even refer to a website which explains setTimeout, although I wouldn't want to make any programmer too lazy ;)
I've seen implementations of sleep on the internet using synchronous ajax requests to a server-side script that calls a sleep function. Although I didn't test it myself I understand the browser is still locked from any user interaction, and of course its precision is dependent on your internet connection. I guess it probably won't take up as much processor-time, but it's still not very practical.
Still there are lots of functions that are marked as unported that are just weird. I am really looking forward to seeing someones implementation of phpinfo(), ini_set() or dl() ;)


Brett Zamir
25 Sep '09
I'm currently using a Worker like this to be able to do GUI testing in an application which asynchronously gets alerts back from a server. The worker repeatedly checks for a specific alert dialogs (this is privileged Firefox extension code) and once it is found (if found), it closes the dialog and moves on with additional tests.
Here is a bare bones example of how one might use a worker for a delay (at least as far as I understood how to use it; it does seem to do the job) with some comments that might help:
// In your application file // 1) Start before this line by doing something you want finished before a delay //CONFIG var workerFile = 'myworker.js'; var secondsDelay = 5; var ID = 1; // Some unique ID which onmessage could increment, etc. (e.g., to know how many tries have been attempted) // SET UP WORKER var worker = new Worker(workerFile); worker.onmessage = function onmessage (ev) { // ev.data is our ID // 3) Now do something, including optionally calling postMessage again (e.g., to retry something; we could check for something, increment the ID, and postMessage for another delay) }; worker.onerror = function(ev) { throw 'Error with worker: '+ev.data; }; // TRIGGER WORKER // Can pass any JSON to postMessage (i.e., no functions, alone or on objects unless as strings) worker.postMessage([secondsDelay, ID]); // 2) optionally undertake some action here which can go on simultaneously with your delay (like trigger an asynchronous event)