user1477955
user1477955

Reputation: 1670

JavaScript self invoking function

I'm trying to understand this example code, what is the function of line 15, why start(timeout)? (Sorry, I'm new to programming)

var schedule = function (timeout, callbackfunction) {
    return {
        start: function () {
            setTimeout(callbackfunction, timeout)
        }
    };
};

(function () {
    var timeout = 1000; // 1 second
    var count = 0;
    schedule(timeout, function doStuff() {
        console.log(++count);
        schedule(timeout, doStuff);
    }).start(timeout);
})();

// "timeout" and "count" variables
 // do not exist in this scope.

Upvotes: 2

Views: 980

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074188

...why start(timeout)?

In that example, there's actually no reason for passing timeout into start, since start doesn't accept or use any arguments. The call may as well be .start().

What's happening is that schedule returns an object the schedule function creates, and one of the properties on that object is called start, which is a function. When start is called, it sets up a timed callback via setTimeout using the original timeout passed into schedule and the callback function passed into schedule.

The code calling schedule turns around and immediately calls the start function on the object it creates.

In the comments, Pointy points out (well, he would, wouldn't he?) that the callback function is calling schedule but not doing anything with the returned object, which is pointless — schedule doesn't do anything other than create and return the object, so not using the returned object makes the call pointless.

Here's the code with those two issues addressed:

var schedule = function (timeout, callbackfunction) {
    return {
        start: function () {
            setTimeout(callbackfunction, timeout)
        }
    };
};

(function () {
    var timeout = 1000; // 1 second
    var count = 0;
    schedule(timeout, function doStuff() {
        console.log(++count);
        schedule(timeout, doStuff).start(); // <== Change here
    }).start();                             // <== And here
})();

It's not very good code, though, frankly, even with the fixes. There's no particularly good reason for creating a new object every time, and frankly if the book is meant to be teaching, this example could be a lot clearer. Inline named function expressions and calls to methods on objects returned by a function...absolutely fine, but not for teaching. Still, I don't know the context, so those comments come with a grain of salt.

Here's a reworked version of using the schedule function by reusing the object it returns, and being clear about what bit is happening when:

(function () {
    var timeout = 1000; // 1 second
    var count = 0;

    // Create the schedule object
    var scheduleObject = schedule(timeout, doStuff);

    // Set up the first timed callback
    scheduleObject.start();

    // This is called by each timed callback
    function doStuff() {
        // Show the count
        console.log(++count);

        // Set up the next timed callback
        scheduleObject.start();
    }
})();

Upvotes: 3

Niels
Niels

Reputation: 49919

The function schedule is executed as a function. That function returns an object. Like you can see with the { start... }. With the returned object it calls out the start function. This is called chaining. So the start function is executed after is set the function.

What is strange is that the timeout is passed to the start function which has no parameters.

Upvotes: 2

Related Questions