1

I am building a JavaScript library. I have be working on a delay function that works like this:

function delay(ms) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > ms){
            break;
        }
    }
}

The idea being that I can do something like this:

window.onload = function() {
  delay(5000);  //this function will act 5 seconds after the page loads
  document.getElementById('Header').innerHTML = 'Welcome';
};

The delay works fine, but it stops all javascript on the page rather than just delaying the window.onload function.

Does anyone know what I can do?

Nobel Chicken
  • 1,533
  • 1
  • 11
  • 13

3 Answers3

6

Use setTimeout instead of your delay method. It won't block the UI and is much cleaner.

setTimeout(function() {
   document.getElementById('Header').innerHTML = 'Welcome';
}, 5000);
Patrick D
  • 6,659
  • 3
  • 43
  • 55
  • Well, that doesn't solve OP problem : he wants a delay function... – Denys Séguret Jun 14 '13 at 15:37
  • 1
    This will execute his function after a 5 second delay. What is missing? – Patrick D Jun 14 '13 at 15:37
  • OP says he want to build a library with a delay function... – Denys Séguret Jun 14 '13 at 15:38
  • 1
    I think what @dystroy means is, the OP wants to create **their own** delay function. – George Jun 14 '13 at 15:38
  • @ dystroy - It is not answering how to make a delay function. @ Patrick D - what you're mirring is that I want to make a function that delays. – Nobel Chicken Jun 14 '13 at 15:38
  • 1
    @CodeApprentice My thoughts too I've no idea why it has so many upvotes. I'm thinking people are not understanding the question too well. – George Jun 14 '13 at 15:39
  • Read into his question. He's asking how to delay a block of code. I doubt he literally is asking how to create an entirely new delay function, with the knowledge that `setTimeout` exists. `setTimeout` solves his problem. – Patrick D Jun 14 '13 at 15:41
  • Keep in mine that I am using this in a javascript library. – Nobel Chicken Jun 14 '13 at 15:43
  • It would help if you described a scenario where `setTimeout` does not work for you. If given the option between choosing a native, async function like timeout, or writing your own custom code; it would make the most sense to choose the native function. If this native solution does not work, for whatever scenario, then my answer may obviously change. – Patrick D Jun 14 '13 at 15:46
  • What you need to understand is that JavaScript is single threaded. This matters. There is literally no code that you can write that will loop forever, without using async callbacks supported by the language, where you could achieve a delay without blocking the UI. – Patrick D Jun 14 '13 at 15:47
4

Your question (and responses to Patrick D's answer) is, I think, based on a misunderstanding.

There is no way to implement code that will do what you want.

A JavaScript environment is single-threaded. (Let's ignore web workers for the moment.) This means that each line executes after the one before it.

If you have a function that occupies this (one and only) thread for 5 seconds, nothing else will run during that 5 seconds. It's as simple as that.

The way we get around this in the JavaScript world is to utilize asynchronous programming, which makes use of callbacks. The setTimeout function is the correct way to solve this problem.

Now, you could do this. Say you want a function that, given some function fn, returns a new function which executes fn after a set delay. You could implement this:

Function.prototype.delay = function(ms) {
    var fn = this;
    return function() {
        setTimeout(fn, ms);
    };
};

Then you could hypothetically write code like the following:

function foo() {
  // something or other
}

var fooDelayed = foo.delay(5000);

// Now this line will execute foo after 5 seconds.
fooDelayed();

If you really want something like that, it's possible. But it is still essentially a wrapper around setTimeout: there's no avoiding that.

See this jsFiddle demonstrating the idea.

Community
  • 1
  • 1
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
2

If you really want to build a function around setTimeout(), you're free to do so:

function delay(ms, callback) {
  setTimeout(callback, ms);
}

There's absolutely no other way for delaying an action or execution of a code block without a blocking mechanism.

And because setTimeout() acts asynchronously, you always have to provide a callback function!

ComFreek
  • 29,044
  • 18
  • 104
  • 156
  • Could you give an example of how this would be used. – Nobel Chicken Jun 14 '13 at 15:48
  • This solution is the same as my answer, it just abstracts out a single parameter. You will STILL have to use callbacks in either scenario. It's exactly the same. – Patrick D Jun 14 '13 at 15:51
  • @PatrickD Absolutely! I can't understand the OP's reasons for the need of this redundant function either. +1 for you btw. – ComFreek Jun 14 '13 at 15:55