Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript method chaining challenge

(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

like image 991
kizzx2 Avatar asked Sep 18 '09 17:09

kizzx2


3 Answers

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.

like image 196
Christian C. Salvadó Avatar answered Oct 13 '22 05:10

Christian C. Salvadó


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);
like image 45
Christoph Avatar answered Oct 13 '22 05:10

Christoph


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);
like image 43
Gumbo Avatar answered Oct 13 '22 06:10

Gumbo