Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript sleep [duplicate]

Yes, I know - that question has thousands of answers. please, don't tell me about setTimeout method because - yes, everything is possible with that but not so easy as using sleep() method.

For example:

function fibonacci(n) {
    console.log("Computing Fibonacci for " + n + "...");
    var result = 0;

    //wait 1 second before computing for lower n
    sleep(1000);
    result = (n <= 1) ? 1 : (fibonacci(n - 1) + fibonacci(n - 2));

    //wait 1 second before announcing the result
    sleep(1000);
    console.log("F(" + n + ") = " + result);

    return result;
}

if you know how to get the same result using setTimeout - tell me ;) fibanacci is pretty easy task, because there aren't more than 2 recursions, but how about n-recursions (like fib(1) + fib(2) + .. + fib(n)) and sleep after every "+"? Nah, sleep would be muuuuuch easier.

But still I can't get working example of implementing it. while (curr - start < time) { curr = (...) } is tricky, but it won't work (just stops my browser and then throw all console logs at once).

like image 384
Diazath Avatar asked Jan 08 '11 13:01

Diazath


2 Answers

The question is asking how to implement sleep() in JavaScript, right?

function sleep(ms) {
  var start = new Date().getTime(), expire = start + ms;
  while (new Date().getTime() < expire) { }
  return;
}

I just tested it like so:

console.log('hello');
sleep(5000);
console.log('world');

Works for me.

(As a meta comment: I landed here because I have a particular need for this function. Such needs do come up when you need to block while waiting for a value. Even in JavaScript.)

like image 177
Murph Avatar answered Oct 26 '22 01:10

Murph


I dont fully understand what you're asking, but I'm going to answer this part:

if you know how to get the same result using setTimeout - tell me

The fundamental difference is that sleep (as used in many other languages) is synchronous, while setTimeout (and many other JavaScript-concepts, like AJAX for example) are asynchronous. So, in order to rewrite your function we have to take this into account. Mainly, we have to use a callback to fetch the "return value", rather than an actual return-statement, so it will be used like this:

fibonacci(7, function(result) {
  // use the result here..
});

So, as for the implementation:

function fibonacci(n, callback) {
  console.log("Computing Fibonacci for " + n + "...");
  var result = 0;

  var announceAndReturn = function() {
    setTimeout(function() {
      // wait 1 second before announcing the result
      console.log("F(" + n + ") = " + result);
      callback(result); // "returns" the value
    }, 1000);
  };

  // wait 1 second before computing lower n
  setTimeout(function() {
    if (n <= 1) {
      result = 1;
      announceAndReturn();
    }
    else {
      var resultsLeft = 2;

      var handler = function(returned) {
        result += returned;
        resultsLeft--;
        if (resultLeft == 0)
          announceAndReturn();
      }

      fibonacci(n-1, handler);
      fibonacci(n-2, handler);
    }
  }, 1000);
}

I would also like to point out that, no, this is not an easier solution than using sleep. Why? Because this code is asynchronous and that's simply more complicated than synchronous code for what most people are used to. It takes practice to start thinking in that way.

The upside? It allows you to write non-blocking algorithms that outperforms their synchronous counterparts. If you haven't heard of Node.js before, you could check it out to further understand the benefits of this. (Many other languages have libraries for dealing with async IO as well, but as long as were talking about JavaScript..)

like image 42
Jakob Avatar answered Oct 26 '22 03:10

Jakob