2016-05-19 4 views
5

Рассмотрим следующий код:Javascript: Обещания + это

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); 
} 

Выход:

undefined 

Но вместо этого, если я сделать следующее:

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); 
} 

Выход:

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

Я не понимаю, почему первый звонок меняется там, где этот точек в функции бара. Может кто-нибудь просветить меня?

+4

Потому что очень важно, как вы называете функцию. Прочтите это: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this. В первом примере вы «отключили» метод из контекстного объекта, так что вы его потеряли. – dfsq

+0

Это не имеет ничего общего с обещаниями, см. [Как получить доступ к правильному 'this'/context внутри обратного вызова?] (Http://stackoverflow.com/q/20279484/1048572) для других решений – Bergi

+0

@dfsq: Я бы даже не используйте термин «смятый». В JS нет методов, функции становятся их только при вызове как свойства объекта. Они не связаны друг с другом. – Bergi

ответ

3

Когда вы передаете self.bar методу then, вы передаете ссылку на функцию. Хотя похоже, что вы также указываете, что он должен быть вызван на объект self, это на самом деле не то, что происходит. Объект self не включен в эту функцию. Значение объекта определяется при вызове функции, а не когда оно определено или передано как аргумент.

В вашем втором примере selfявляетсяthis объекта в контексте функции, потому что это, где вы вызова функции от.

Другой способ заставить его работать - заставить объект this объекта всегда быть self, переопределяя описанное выше поведение. Вы можете достичь этого с помощью .bind():

Promise.all([p1, p2]) 
    .then(self.bar.bind(self)); 
Смежные вопросы