Jedynym problemem związanym z obietnicami jest to, że IE ich nie obsługuje. Edge ma, ale jest mnóstwo IE 10 i 11: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise (kompatybilność na dole)
JavaScript jest więc jednowątkowy. Jeśli nie wykonujesz połączenia asynchronicznego, będzie ono działało przewidywalnie. Główny wątek JavaScript wykona jedną funkcję całkowicie przed wykonaniem następnej, w kolejności, w jakiej występują w kodzie. Gwarantowanie kolejności funkcji synchronicznych jest banalne - każda funkcja wykona się całkowicie w kolejności, w której została wywołana.
Pomyśl o funkcji synchronicznej jako atomowej jednostce pracy . Główny wątek JavaScript wykona go w pełni, w kolejności, w jakiej instrukcje pojawiają się w kodzie.
Ale wrzuć wywołanie asynchroniczne, jak w następującej sytuacji:
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
To nie robi tego, co chcesz . Natychmiast wykonuje funkcję 1, funkcję 2 i funkcję 3. Ładowanie div miga i zniknęło, podczas gdy wywołanie ajax nie jest prawie ukończone, mimo że makeAjaxCall()
zostało zwrócone. POWIKŁANIE polega na tym, że makeAjaxCall()
podzielił on swoją pracę na części, które są stopniowo zwiększane o każdy obrót głównego wątku JavaScript - zachowuje się asychronicznie. Ale ten sam główny wątek, podczas jednego wirowania / przebiegu, wykonał synchroniczne części szybko i przewidywalnie.
Sposób w jaki sobie z tym poradziłem : Jak powiedziałem, funkcją jest atomowa jednostka pracy. Połączyłem kod funkcji 1 i 2 - kod funkcji 1 umieściłem przed funkcją asynch. Pozbyłem się funkcji 1. Wszystko, włącznie z wywołaniem asynchronicznym, wykonuje się przewidywalnie, w kolejności.
NASTĘPNIE, gdy zakończy się asynchroniczne wywołanie, po kilku obrotach głównego wątku JavaScript, niech wywoła funkcję 3. To gwarantuje kolejność . Na przykład w przypadku ajax program obsługi zdarzeń onreadystatechange jest wywoływany wiele razy. Kiedy zgłosi, że jest zakończone, wywołaj ostatnią żądaną funkcję.
Zgadzam się, że jest bałagan. Lubię, żeby kod był symetryczny, lubię, żeby funkcje wykonywały jedną rzecz (lub blisko niego) i nie lubię, aby wywołanie ajax w jakikolwiek sposób odpowiadało za wyświetlanie (tworzenie zależności od wywołującego). ALE, z asynchronicznym wywołaniem wbudowanym w funkcję synchroniczną, konieczne są kompromisy w celu zagwarantowania kolejności wykonania. I muszę kodować dla IE 10, więc nie obiecuję.
Podsumowanie : W przypadku połączeń synchronicznych zagwarantowanie porządku jest banalne. Każda funkcja wykonuje się w pełni w kolejności, w jakiej została wywołana. W przypadku funkcji z wywołaniem asynchronicznym jedynym sposobem na zagwarantowanie kolejności jest monitorowanie, kiedy zakończy się wywołanie asynchroniczne, i wywoływanie trzeciej funkcji po wykryciu tego stanu.
Dyskusje na temat wątków JavaScript można znaleźć na stronie : https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23 i https://developer.mozilla.org/en-US/docs/Web/JavaScript/ EventLoop
Kolejne podobne, wysoko ocenione pytanie na ten temat: Jak wywołać 3 funkcje, aby wykonać je jedna po drugiej?
firstFunction
dokładnie to powoduje, że jest asynchroniczny? Tak czy inaczej - sprawdź obietnice