Jaka jest różnica pomiędzy:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return "bbb";
})
.then(function(result) {
console.log(result);
});
i to:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return Promise.resolve("bbb");
})
.then(function(result) {
console.log(result);
});
Pytam, gdy dostaję inne zachowanie Używanie usługi Angular i $ http z łańcuchem .then (). Trochę za dużo kodu, stąd pierwszy przykład powyżej.
javascript
angularjs
promise
q
spirytus
źródło
źródło
Promise.resolve()
W drugim przykładzie nie jest konieczne.then
opiekuna, w rzeczywistości jest to kluczowy aspekt specyfikacji obietnic, że możesz to zrobić.then
s - termin „inne języki” oznacza, żethen
jest to zarówno a, jakmap
i aflatMap
.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));
ten kod po prostu zawiesi się (nie zostanie rozwiązany na zawsze). Ale jeśli zmienięreturn "haha";
na,return res("haha");
to zadziała i ostrzeże „haha”. Czy funkcja fetch (). Then () nie zawijała już słowa „haha” w obietnicę?Odpowiedzi:
Zasada jest taka, że jeśli funkcja w
then
module obsługi zwraca wartość, obietnica rozwiązuje / odrzuca tę wartość, a jeśli funkcja zwraca obietnicę, co się dzieje, następnathen
klauzula będziethen
klauzulą obietnicy zwróconej przez funkcję , więc w tym przypadku pierwszy przykład przechodzi przez normalną sekwencjęthens
i wypisuje wartości, jak można się spodziewać, w drugim przykładzie obiekt obietnicy, który jest zwracany, gdy to robiszPromise.resolve("bbb")
, to ten,then
który jest wywoływany podczas łączenia (dla wszystkich zamiarów i celów). Sposób, w jaki to działa, opisano bardziej szczegółowo poniżej.Cytowanie ze specyfikacji Promises / A +:
Kluczową rzeczą, którą należy tutaj zauważyć, jest ta linia:
źródło
then
zwróci obietnicę. +1 za odniesienie do specyfikacji.[[Resolve]]
jest wywoływany zarówno wthen
ables, jak i wartościach, więc zasadniczo otacza wartość obietnicą, więcreturn "aaa"
jest taki samreturn Promise.resolve("aaa")
ireturn Promise.resolve("aaa")
jest taki sam jakreturn Promise.resolve(Promise.resolve("aaa"))
- ponieważ rozdzielczość jest idempotentna, nazywając ją wartością więcej niż raz ma ten sam wynik."aaa"
ireturn Promise.resolve("aaa")
jest wymiennythen
we wszystkich przypadkach?Mówiąc najprościej, wewnątrz
then
funkcji modułu obsługi:A) Kiedy
x
jest wartością (liczba, ciąg itp.):return x
jest równareturn Promise.resolve(x)
throw x
jest równareturn Promise.reject(x)
B) Kiedy
x
obietnica jest już rozliczona (nie jest już w toku):return x
jest równoważnereturn Promise.resolve(x)
, jeśli obietnica została już rozwiązana.return x
jest równoważnereturn Promise.reject(x)
, jeśli obietnica została już odrzucona.C) Kiedy
x
nadchodzi obietnica:return x
zwróci oczekującą Obietnicę i zostanie oceniona na podstawie kolejnejthen
.Przeczytaj więcej na ten temat w dokumentach Promise.prototype.then () .
źródło
Oba twoje przykłady powinny zachowywać się prawie tak samo.
Wartość zwrócona w
then()
module obsługi staje się wartością rozdzielczości obietnicy zwróconej z tej wartościthen()
. Jeśli wartość zwrócona w.then
obietnicy jest obietnicą, zwrócona przez nią obietnicathen()
„przyjmie stan” tej obietnicy i rozwiąże / odrzuci tak, jak robi to obietnica zwrócona.W pierwszym przykładzie zwracasz
"bbb"
w pierwszymthen()
module obsługi, więc"bbb"
jest on przekazywany do następnego modułuthen()
obsługi.W drugim przykładzie zwracana jest obietnica, która jest natychmiast rozpatrywana za pomocą wartości
"bbb"
, więc"bbb"
jest przekazywana do następnego modułuthen()
obsługi. (Promise.resolve()
Tutaj jest obce).Wynik jest taki sam.
Jeśli możesz pokazać nam przykład, który faktycznie wykazuje inne zachowanie, możemy powiedzieć, dlaczego tak się dzieje.
źródło
Promise.resolve();
vsreturn;
?undefined
zamiast"bbb"
.Masz już dobrą formalną odpowiedź. Pomyślałem, że powinienem dodać krótki.
Następujące rzeczy są identyczne z obietnicami / obietnicami A + :
Promise.resolve
(w twoim przypadku Angular to jest$q.when
)new $q
.then
wywołania zwrotnego.Zatem poniższe są identyczne dla obietnicy lub zwykłej wartości X:
I nie jest zaskoczeniem, że specyfikacja obietnic oparta jest na procedurze rozwiązywania obietnic, która umożliwia łatwą współpracę między bibliotekami (np. $ Q i natywnymi obietnicami) i ogólnie ułatwia życie. Ilekroć może dojść do rozwiązania obietnicy, pojawia się rozwiązanie zapewniające ogólną spójność.
źródło
Promise.resolve().then(function(){ return x; });
? Znalazłem wyciętego robiącego coś podobnego (nazywało się to funkcją wewnątrzthen
bloku). Myślałem, że to mniej więcej tak, jak zrobić przerwę, ale jest to trochę szybsze. jsben.ch/HIfDowith
bloku nad obiektem lub serwerem proxy zx
akcesorem właściwości, który zgłasza wyjątek. W takim przypadku Promise.resolve (x) spowodowałoby zgłoszony błąd, alePromise.resolve().then(function(){ return x; });
byłby odrzuconą obietnicą, ponieważ błąd został zgłoszony in athen
).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }
. Tutaj obietnica nie jest przypisana, więc po co? Przekroczenie czasu miałoby (mniej więcej) ten sam efekt, czy nie?Jedyna różnica polega na tym, że tworzysz niepotrzebną obietnicę
return Promise.resolve("bbb")
. Zwrócenie obietnicy od przewodnikaonFulfilled()
rozpoczyna rozstrzyganie obietnicy . Tak działa łańcuch obietnic .źródło