Jak rozumiem, obietnica jest czymś, co może rozwiązać () lub odrzucić (), ale byłem zaskoczony, gdy dowiedziałem się, że kod w obietnicy nadal jest wykonywany po wywołaniu rozwiązania lub odrzucenia.
Rozważałem rozwiązanie lub odrzucenie bycia przyjazną asynchronicznie wersją wyjścia lub powrotu, która zatrzymałaby wszystkie natychmiastowe wykonywanie funkcji.
Czy ktoś może wyjaśnić, dlaczego poniższy przykład czasami pokazuje plik console.log po wywołaniu rozwiązania:
var call = function() {
return new Promise(function(resolve, reject) {
resolve();
console.log("Doing more stuff, should not be visible after a resolve!");
});
};
call().then(function() {
console.log("resolved");
});
javascript
promise
ecmascript-6
es6-promise
Ludwig Van Beethoven
źródło
źródło
resolve()
nie jest instrukcją sterującą JS, która w magiczny sposób miałaby wpływreturn
, to tylko wywołanie funkcji i tak, wykonanie jest kontynuowane po nim.Odpowiedzi:
JavaScript ma koncepcję „biegnij do końca” . O ile nie zostanie zgłoszony błąd, funkcja jest wykonywana do momentu osiągnięcia
return
instrukcji lub jej końca. Inny kod poza funkcją nie może w to przeszkadzać (chyba że ponownie zostanie zgłoszony błąd).Jeśli chcesz
resolve()
wyjść z funkcji inicjalizatora, musisz ją poprzedzićreturn
:return new Promise(function(resolve, reject) { return resolve(); console.log("Not doing more stuff after a return statement"); });
źródło
resolve()
jest sama w sobie funkcją asynchroniczną. Jak widzieliśmy w drugiej (usuniętej) odpowiedzi, niektórzy uważają, że wywołanieresolve
natychmiast uruchomi wszelkie wywołania zwrotne.resolve
Sam @Alnitak nie jest asynchroniczny, jest całkowicie synchroniczny. Chociaż używa się ściśle ES6 API, nie można zaobserwować, czy jest synchroniczne, czy asynchroniczne.resolve
spowoduje natychmiastowe wywołanie wszystkich zarejestrowanych wywołań zwrotnych, tak że są one częścią bieżącego stosu wywołań. To nieprawda, zamiast tego po prostu kolejkuje wywołania zwrotne (i masz rację, nie jest asynchroniczny, ale po prostu robi swoje i natychmiast się kończy)console.log
pojawia się zamiast, zamiast dlaczego pojawia się w tej kolejności. Jak dotąd to, coresolve
spełnia i jak obiecuje, nie ma znaczenia dla tego, jak interpretuję pytanie. Ale oczywiście nadal ważne jest, aby wiedzieć w kontekście obietnic. Jednym z powodów, dla których zagłosowałem za twoją odpowiedzią :)Wywołania zwrotne, które będą wywoływane podczas
resolve
obietnicy, nadal wymagają, aby specyfikacja była wywoływana asynchronicznie. Ma to na celu zapewnienie spójnego zachowania podczas korzystania z obietnic dla kombinacji działań synchronicznych i asynchronicznych.Dlatego po wywołaniu
resolve
wywołanie zwrotne jest umieszczane w kolejce , a wykonywanie funkcji jest kontynuowane natychmiast z dowolnym kodem następującym poresolve()
wywołaniu.Dopiero gdy pętla zdarzeń JS odzyska kontrolę, wywołanie zwrotne może zostać usunięte z kolejki i faktycznie wywołane.
źródło
EnqueueJob
, która jest wywoływana przez.then
.