2016-04-07 7 views
5

Zwykle, jeśli nie używasz obietnice można łatwo zrobićpowiązać `this` zakres funkcji obietnica zwrotnej

var a = function(cb){ 
    setTimeout(function(){ 
    var boundCb = cb.bind({hello: 'world'}); 
    boundCb(); 
    }, 100); 
}; 

a(function(){ 
    alert(this.hello); 
}); 

który nie jest szczególnie przydatna w większości przypadków (jak można przekazać takie same rzeczy jako normalne argumenty), ale pozwala na bardzo czytelny kod i/lub proste w użyciu interfejsy.

Po przejściu na obietnice nagle staje się o wiele trudniejsze. Nic więc dziwnego następujące nie pracy (jak resolve nie ma bezpośredniego odniesienia)

var a = function(){ 
    return new Promise(function(resolve, reject){ 
    var boundResolve = resolve.bind({hello: 'word'}); 
    boundResolve(); 
    }); 
}; 

a().then(function(){ 
    alert(this.hello) 
}); 

więc jest jakiś sposób w ogóle do osiągnięcia tego celu?


nieniezbędnymi postscriptum: „Na szczęście” w mojej sytuacji zakres this Chcę ustawić jest już takie samo jak to, co jest zakres this w a(). Obecnie po prostu piszę .bind(this) po każdej funkcji wywołania zwrotnego Promise, aw przyszłości będę mógł używać do tego funkcji strzałek, ale w międzyczasie szukam czystszego rozwiązania.

+0

To nie wydaje się być bardzo dobry pomysł, aby mnie. Chcesz powiązać obietnicę z jakąś wartością "this" podczas jej tworzenia, a następnie w jakimś zupełnie osobnym miejscu, odwołać się do tej wartości za pomocą "this"? Wygląda to jak prawdziwy drapak dla każdego, kto zachowuje twój kod, łamiąc zasadę najmniejszego zdziwienia (https://en.wikipedia.org/wiki/Principle_of_least_astonishment). – JLRishe

+1

@JLRishe: Z punktu widzenia API może to mieć wiele sensu, ale trzeba by spojrzeć na szerszy kontekst konkretnej sprawy, aby to zrozumieć. (Elementy polimerowe, w których "to" ma wygląd zewnętrzny, powinny zawsze odnosić się do bieżącego elementu.) –

+0

Wystarczająco sprawiedliwe. :) – JLRishe

Odpowiedz

4

Natywne obietnice nie oferują tej funkcji. Jednak biblioteka Bluebird Obietnica oferuje Promise.prototype.bind

Oto przykład użycia

MyClass.prototype.method = function() { 
    return fs.readFileAsync(this.file).bind(this) 
    .then(function(contents) { 
     var url = urlParse(contents); 
     return this.httpGetAsync(url); // this is bound to the MyClass instance 
    }).then(function(result) { 
     // this is still bound, further down the chain. 
     var refined = this.refine(result); 
     return this.writeRefinedAsync(refined); 
    }).catch(function(e) { 
     this.error(e.stack); // Even in event handlers 
    }); 
};
+0

Tak, obawiałem się, że @ "Native Promises nie oferują tej funkcjonalności.". Nie chciałem jednak spieszyć się z wnioskami przed pierwszym sprawdzeniem :). Naprawdę nie miałbym nic przeciwko, gdyby dodali to do API, byłoby użyteczne na wiele sposobów. –

+3

Objaśnienia zwrotne są zaprojektowane z myślą o bezpaństwowości. "to" oznacza stan, który nie jest "czystą drogą". –

+0

Nie próbuję dać im żadnego stanu (jako że chcę "związać" szerszy "ten" zakres "z powrotem"), ale całkowicie rozumiem to, co mówisz. –

Powiązane problemy