Mój kod:
let AuthUser = data => {
return google.login(data.username, data.password).then(token => { return token } )
}
A kiedy próbuję uruchomić coś takiego:
let userToken = AuthUser(data)
console.log(userToken)
Otrzymuję:
Promise { <pending> }
Ale dlaczego?
Moim głównym celem jest uzyskanie tokena, z google.login(data.username, data.password)
którego zwraca obietnicę, do zmiennej. I dopiero wtedy wykonaj pewne czynności.
getFirstUser
funkcjęOdpowiedzi:
Obietnica będzie zawsze rejestrowana jako oczekująca, o ile jej wyniki nie zostaną jeszcze rozwiązane. Musisz odwołać
.then
się do obietnicy, aby uchwycić wyniki niezależnie od stanu obietnicy (rozwiązany lub wciąż oczekujący):Dlaczego?
Obietnice dotyczą tylko kierunku naprzód; Możesz je rozwiązać tylko raz. Rozstrzygnięta wartość a
Promise
jest przekazywana do jej metod.then
lub.catch
.Detale
Zgodnie ze specyfikacją Promises / A +:
Ta specyfikacja jest trochę trudna do przeanalizowania, więc podzielmy ją. Zasada jest taka:
Jeśli funkcja w programie
.then
obsługi zwraca wartość, to jestPromise
rozwiązywana z tą wartością. Jeśli przewodnik zwróci innyPromise
, oryginał zostaniePromise
rozstrzygnięty z rozstrzygniętą wartością łańcuchaPromise
. Następny.then
program obsługi zawsze będzie zawierał rozstrzygniętą wartość połączonej obietnicy zwróconej w poprzednim.then
.Sposób, w jaki to faktycznie działa, opisano bardziej szczegółowo poniżej:
1. Zwrot
.then
funkcji będzie ustaloną wartością promesy.2. Jeśli
.then
funkcja zwraca aPromise
, to rozwiązana wartość tej połączonej obietnicy jest przekazywana do następującego.then
.źródło
Uncaught SyntaxError: Unexpected token .
. Drugi potrzebuje powrotuPromise
.then
pełnić funkcji, której nie wezwano. zaktualizował odpowiedźWiem, że to pytanie zostało zadane 2 lata temu, ale napotykam ten sam problem, a odpowiedź na problem jest taka, że od ES6 można po prostu
await
funkcje zwracać wartość, na przykład:źródło
.then(token => return token)
, to tylko niepotrzebne przejście. Po prostu oddzwoń na połączenie logowania Google.await
poza funkcją asynchroniczną. Być może lepszym przykładem byłoby tutaj utworzenieAuthUser
funkcjiasync
, która następnie kończy się nareturn await google.login(...);
then
Metoda zwraca oczekujące obietnicę, które mogą być rozwiązane w sposób asynchroniczny o wartości zwracanej handlera wynik zarejestrowany w wywołaniuthen
lub odrzucony przez rzucanie błąd wewnątrz przewodnika nazwie.Tak więc wywołanie
AuthUser
nie spowoduje nagłego zalogowania użytkownika synchronicznie, ale zwróci obietnicę, której następnie zarejestrowane procedury obsługi zostaną wywołane po pomyślnym (lub niepowodzeniu) logowania. Sugerowałbym wyzwalanie całego przetwarzania logowaniathen
klauzulą obietnicy logowania. EG używając nazwanych funkcji do wyróżnienia sekwencji przepływu:źródło
Zobacz sekcję MDN dotyczącą obietnic. W szczególności spójrz na zwracany typ then ().
Aby się zalogować, agent użytkownika musi wysłać żądanie do serwera i czekać na odpowiedź. Ponieważ całkowite wstrzymanie wykonywania aplikacji podczas przesyłania żądania w obie strony zwykle powoduje złe wrażenia użytkownika, praktycznie każda funkcja JS, która loguje Cię (lub wykonuje jakąkolwiek inną formę interakcji z serwerem), będzie używać Obietnicy lub czegoś bardzo podobnego , aby dostarczać wyniki asynchronicznie.
Zauważ też, że
return
instrukcje są zawsze oceniane w kontekście funkcji, w której się pojawiają. Kiedy więc napisałeś:instrukcja
return token;
oznaczała, że przekazywana funkcja anonimowathen()
powinna zwracać token, a nieAuthUser
funkcja powinna. To, coAuthUser
wraca, jest wynikiem wezwaniagoogle.login(username, password).then(callback);
, które okazuje się być obietnicą.Ostatecznie twój callback
token => { return token; }
nic nie robi; zamiast tego dane wejściowethen()
muszą być funkcją, która w jakiś sposób obsługuje token.źródło
return
traktowana jest nowa (ish) składnia domknięcia, w którym to przypadku - cóż, zdecydowanie tego nie pochwalam, ale błąd nadal jest mój i przepraszam za niego.token => { return token; }
nie robi nic w przeciwieństwie do twierdzenia, że przynosi efekt przeciwny do zamierzonego. Możesz mówićgoogle.login(username, password).then(token=>{return token;}).then(token=>{return token;})
i tak dalej w nieskończoność, ale uzyskasz tylko zwrócenie wyniku,Promise
który zostanie rozpatrzony za pomocą żetonu - tak samo, jakbyś zostawił go jakogoogle.login(username, password);
. Nie jestem pewien, dlaczego uważasz, że jest to „bardzo złe”.return token
nie działa zgodnie z oczekiwaniami OP.promise.then(result => { return result; })
dokładnie równoważne zpromise
, dlatego wywołanie metody nic nie robi i należy je porzucić, aby uprościć kod i zwiększyć czytelność - stwierdzenie, które jest całkowicie prawdziwe.Twoja obietnica oczekuje na realizację, wypełnij ją do
po pozostałym kodzie. Wszystko, co robi ten kod, to
.then()
wypełnienie obietnicy i uchwycenie wyniku końcowego w postaci zmiennej wyniku i wyniku drukowania w konsoli. Pamiętaj, że nie możesz przechowywać wyniku w zmiennej globalnej. Mam nadzieję, że to wyjaśnienie może ci pomóc.źródło