15

Consider the following code:

foo: function() {
  var self = this;
  var p1 = p2 = someFunctionThatReturnsAPromise();

  Promise.all([p1, p2])
    .then(self.bar);
}

bar: function(promises) {
  var self = this;
  console.log(self);
}

Output:

undefined

But if I do the following instead:

foo: function() {
  var self = this;
  var p1 = p2 = someFunctionThatReturnsAPromise();

  Promise.all([p1, p2])
    .then(function(result) {
      self.bar(result);
    });
}

bar: function(promises) {
  var self = this;
  console.log(self);
}

Output:

{ foo: [Function],
  bar: [Function] }

I don't understand why the first call changes where this points in the bar function. Can someone enlighten me?

3
  • 4
    Because it's very important how you call a function. Read this: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… In your first example you "detouched" method from context object, so you lost it. Commented May 19, 2016 at 21:28
  • This has nothing to do with promises, see How to access the correct this / context inside a callback? for other solutions Commented May 19, 2016 at 21:39
  • @dfsq: I wouldn't even use the term "detouched". There are no methods in JS, functions become them only when being called as object properties. They're unbound otherwise. Commented May 19, 2016 at 21:40

1 Answer 1

11

When you pass self.bar to the then method, you pass a function reference. Although it looks like you also specify it should be called on the self object, that is actually not what is happening. The self object is not included in that function reference. The this object's value is determined when a function is called, not when it is defined or passed as argument.

In your second example, self is the this object within the function context, because that is where you call the function from.

Another way to get it working is to force the function's this object to always be self, overriding the above described behaviour. You can achieve that with .bind():

Promise.all([p1, p2])
    .then(self.bar.bind(self));
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.