Warrshrike
Warrshrike

Reputation: 136

Are callbacks in Javascript really methods calls? If so how are they 'cascaded'?

For example, take this code from Angular.js:

app.config(function ($routeProvider) {
   $routeProvider
       .when('/', {
           templateUrl: 'page/hello.html',
           controller: 'mainCount'
       })
       .when('/pag', {
           templateUrl: 'page/hello.html',
           controller: 'secondCount'
       })
});

So $routeProvider is an object, and it seems like .when (the callback) is a function invocation. If so, how do these two method calls above get invoked 'one on top of the other'?

Normally, I'd expect this to happen:

object.method().method()

the second method invokes on the object returned by the first method. Clearly, this is not happening in the Angular example above. So what's going on here?

Upvotes: 0

Views: 51

Answers (2)

georgeawg
georgeawg

Reputation: 48968

The .when method of $routeProvider is returning its this in order to allow chaining. Each call to .when adds to the list of stored routes.

$routeProvider = function $routeProvider() {
  this.routeList = [];
};

$routeProvider.prototype.when = function when(string,object) {
  this.routeList.push(string, object);
  return this;
};

Similarly for a $q promise, the .then method gives the $q service a function to be called at a later time which the $q service stores on its list or its "queue" but in that case it returns a new promise. Each successive call to the .then method returns a new promise.

This is an extremely important point. Promises do not return mutated versions of themselves. They return new promises with their .then method. Lack of this understanding has been the folly of many library developers.

Upvotes: 0

Quentin
Quentin

Reputation: 943967

Are callbacks in Javascript really methods calls?

Maybe. Being a method is orthogonal to being a callback.

A method call is when a function attached to an object is called.

A callback is a function that is passed as an argument to another function call.

It is possible that a function which accepts a callback will attach it to an object and call it in that context, but not required.

So $routeProvider is an object, and it seems like .when (the callback)

when isn't a callback in this instance. Promises have a method called when which accepts a callback as an argument, but you aren't dealing with a promise here and you aren't passing a function to when.

.when (the callback) is a function invocation.

Yes. The return value of when is an object. That object is the same object that the first when was invoked on, and it still has a property called when whose value is a function.

This is method chaining not callbacks.

So what's going on here?

Just sensible return values. Take a look at this simple example:

function Incrementor() {
  this.value = 0;
}

Incrementor.prototype.up = function() {
  this.value++;
  return this;
}

var i = new Incrementor();

document.body.appendChild(
  document.createTextNode(
    i.up().up().up().value
  )
);

Upvotes: 2

Related Questions