admin管理员组文章数量:1278690
I know there are many methods like setTimeout, but I just want a REAL one.
I'm using JavaScript to write a piler, and I have to find out a way to implement the sleep() function. I know that buggy loop way, it's not what I want.
Thanks.
I know there are many methods like setTimeout, but I just want a REAL one.
I'm using JavaScript to write a piler, and I have to find out a way to implement the sleep() function. I know that buggy loop way, it's not what I want.
Thanks.
Share Improve this question edited Feb 1, 2011 at 3:05 Xhacker Liu asked Feb 1, 2011 at 2:55 Xhacker LiuXhacker Liu 1,6181 gold badge18 silver badges25 bronze badges 8- By real, you mean? What are you design reqs? – Jared Farrish Commented Feb 1, 2011 at 2:57
- 5 Why would you need to sleep() while piling code? – Metal Commented Feb 1, 2011 at 2:59
- This is a bad idea if you're planning to run this code in a browser and your goal isn't to freeze the UI. – ide Commented Feb 1, 2011 at 3:00
- 1 I'm writing a piler, and the original language has a sleep() function. – Xhacker Liu Commented Feb 1, 2011 at 3:01
- Is Javascript your development language for the piler or your target environment? In other words, are you just writing the piler in Javascript, or will the piler generate Javascript as its "machine language" to be run in a browser or other JS runtime? – paxdiablo Commented Feb 1, 2011 at 3:16
5 Answers
Reset to default 5From the answers above i gather that you want a sleep function that doesnt freeze the browser and doesnt use setTimeout.
Good luck with that, javascript is single threaded. This is NOT possible
You can't, at least in most browser implementations. You'll have to make your piler work around that. StratifiedJS does something similar.
I'll add some more detail. This, obviously, is not the best way to implement a sleep function, but since you said you're doing a simple drawing language, I'll just go with this:
Imagine you have some code like this:
drawLine(1, 2, 3, 4);
sleep(1000);
drawLine(5, 6, 7, 8);
That could be converted into this by breaking up all the sleep
s:
var pieces;
function advance() {
pieces.shift()();
}
pieces=[
function() {
drawLine(1, 2, 3, 4);
setTimeout(advance, 1000);
},
function() {
drawLine(5, 6, 7, 8);
}
];
advance();
Or, if your language is more plex than that, you could do this with more plexity for the piler (this is the obvious solution):
drawLine(1, 2, 3, 4);
setTimeout(function() {
drawLine(5, 6, 7, 8);
}, 1000);
Again, this may not be applicable if your language gets very plex, but it may be helpful as a starting point.
Sounds to me like you want to take a block loop
while(condition) {
// do something
sleep(x);
}
and turn it into
function foo(values) {
if(condition) {
// do something
setTimeout(function() {
foo(values);
}, x);
}
}
foo(someValue);
Also you can take a for loop
for (var i = 0; i < n; i++) {
// do something
sleep(x);
}
and turn it into
function foo(i) {
// do something
i++;
if (i < n) {
setTimeout(function() {
foo(i);
}, x);
}
}
foo(0);
Basically turn your loops into recursive calls then replace your sleeps with asynchrous recursive calls.
In a loop you need to physically block to slow down the step. In recursion you can delay the call to the next recursive function.
The only real and reasonable way to implement sleep()
in JavaScript (at least in the browser environment) is to use setTimeout
. Just process your piled instructions one by one, and then take a break when you encounter the sleep instruction:
function resume() {
while (instructions.length) {
var instruction = instructions.shift();
switch (instruction.opcode) {
case "foo":
doFoo(instruction.operands);
break;
case "bar":
doBar(instruction.operands);
break;
case "sleep":
doSleep(instruction.operands);
return; // pause running
}
}
}
function doSleep(operands) {
setTimeout(resume, operands[0]);
}
var instructions = pile(source);
resume();
If you just want to call a function in X milliseconds you can use setTimeout
, but you knew that.
You can hack things together using Date and getTime
.
function sleep(milliseconds) {
var now = new Date();
var exitTime = now.getTime() + milliseconds;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}
stolen from here
However you are totally freezing the current thread for a possible long period of time. I think you would basically be stopping all javscript action on the page for X milliseconds, which would be very annoying if the time is greater than 300ms.
there's some pretty good analysis of javscript sleep methods here.
If you give us a little more context we can probably be more helpful. Sleep is usually used in multithreaded scenarios in other languages, which is exactly why is was left out of javascript. What features do you need in your piler? :D
本文标签: How to make a REAL sleep() in JavaScriptStack Overflow
版权声明:本文标题:How to make a REAL sleep() in JavaScript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741299491a2371008.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论