2016-05-19 27 views
5

Si consideri il seguente codice:JavaScript: Promises + questo

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

uscita:

undefined 

Ma se faccio la seguente invece:

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

uscita:

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

Non capisco perché la prima chiamata cambia dove questo punti nella funzione della barra. Qualcuno può illuminarmi?

+4

Perché è molto importante come si chiama una funzione. Leggi questo: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this Nel tuo primo esempio hai "smontato" il metodo dall'oggetto contesto, quindi l'hai perso. – dfsq

+0

Questo non ha nulla a che fare con le promesse, vedi [Come accedere al corretto 'this'/contesto all'interno di un callback?] (Http://stackoverflow.com/q/20279484/1048572) per altre soluzioni – Bergi

+0

@dfsq: I wouldn usare anche il termine "detouched". Non ci sono metodi in JS, le funzioni diventano solo quando vengono chiamati come proprietà dell'oggetto. Al contrario, non sono legati. – Bergi

risposta

3

Quando si passa self.bar al metodo then, si passa un riferimento di funzione. Anche se sembra che tu specifichi che dovrebbe essere chiamato sull'oggetto self, che in realtà non è ciò che sta accadendo. L'oggetto self non è incluso in quel riferimento di funzione. Il valore dell'oggetto this viene determinato quando viene chiamata una funzione, non quando viene definita o passata come argomento.

Nel vostro secondo esempio, selfè l'oggetto this nel contesto funzione, perché è lì che si chiamata la funzione da.

Un altro modo per farlo funzionare è forzare l'oggetto this della funzione a essere sempre self, ignorando il comportamento sopra descritto. È possibile ottenere ciò con .bind():

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