Xhacker Liu
Xhacker Liu

Reputation: 1618

How to make a REAL sleep() in JavaScript?

I know there are many methods like setTimeout, but I just want a REAL one.

I'm using JavaScript to write a compiler, 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.

Upvotes: 2

Views: 3754

Answers (5)

Ateş Göral
Ateş Göral

Reputation: 140152

The only real and reasonable way to implement sleep() in JavaScript (at least in the browser environment) is to use setTimeout. Just process your compiled 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 = compile(source);
resume();

Upvotes: 1

icktoofay
icktoofay

Reputation: 129139

You can't, at least in most browser implementations. You'll have to make your compiler 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 sleeps:

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 complex than that, you could do this with more complexity for the compiler (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 complex, but it may be helpful as a starting point.

Upvotes: 4

Raynos
Raynos

Reputation: 169531

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.

Upvotes: 2

mkoryak
mkoryak

Reputation: 57988

From 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

Upvotes: 5

Gordon Gustafson
Gordon Gustafson

Reputation: 41259

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 compiler? :D

Upvotes: 0

Related Questions