views:

475

answers:

4

(This question is not really restricted to the language so please feel free to submit solution in other languages too.)

I was just wondering if it would be possible to write something like this in JavaScript:

// Wait 3 seconds and then say our message in an alert box
wait(3).then(function(){alert("Hello World!");});

Where the traditional way would be to write

// Wait 3 seconds and then say our message in an alert box
setTimeout(function(){alert("Hello World!");}, 3000);

Sorry if this is a noob question :p

+24  A: 

You can write it easily:

function wait(delay) {
  return {
    then: function (callback) {
      setTimeout(callback, delay*1000);
    }
  };
}

wait(3).then(function(){alert("Hello World!");});

If you want to go in-deep, I recommend you to read about currying and partial function application, those topics are really interesting.

CMS
Beat me too it!!!
Zoidberg
Fast typer badge. (or was that ready?)
Cem Kalyoncu
@cemkalyoncu: I'm a fast typist, and I use Vim-like edition everywhere :-D
CMS
+1 Nicely done.
Josh Stodola
Thank you @Josh
CMS
+1  A: 

If you do OO Javascript, then yes, you can do method chaining.

Some of the popular JavaScript frameworks do this. jQuery does this by returning the jQuery object for functions that usually wouldn't return a value.

R. Bemrose
+1  A: 

Chaining is rather used to execute multiple methods on one object. So you would rather consider the function as the object and set the timeout there:

Function.prototype.callAfter = function(delay) {
    setTimeout(this, delay*1000);
};

(function(){alert("Hello World!");}).callAfter(3);
Gumbo
+7  A: 

Yet another version, without closure:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
};

With some more code, you can even call the functions repeatedly:

function wait(seconds) {
    if(this instanceof wait)
        this.delay = seconds;
    else return new wait(seconds);
}

wait.prototype.then = function(callback) {
    setTimeout(callback, this.delay * 1000);
    return this;
};

wait.prototype.wait = function(seconds) {
    this.delay += seconds;
    return this;
};

var start = new Date;
function alertTimeDiff() {
    alert((new Date - start)/1000);
}

wait(1).then(alertTimeDiff).wait(3).then(alertTimeDiff);
Christoph
@Christoph: Your approach is good and is what I think to be more comprehensive than CMS'. But then again he answered the question correctly faster so I gave the correct answer to him :p
kizzx2