Co decyduje o tym, które funkcje JavaScript blokują, a które nie blokują?


27

Od kilku lat zajmuję się JavaScriptem (Vanilla JS, jQuery, Backbone itp.), A ostatnio pracowałem z Node.js. Trochę czasu zajęło mi zrozumienie programowania „nieblokującego”, ale teraz przyzwyczaiłem się do używania wywołań zwrotnych do operacji we / wy i tak dalej.

Rozumiem, że JavaScript jest z natury jednowątkowy. Rozumiem pojęcie „kolejki zdarzeń” węzła. Nie rozumiem, co decyduje o tym, czy pojedyncza operacja javascript „blokuje”, a „nie blokuje”. Skąd mam wiedzieć, na których operacjach mogę polegać, aby uzyskać dane wyjściowe synchronicznie, aby użyć ich w późniejszym kodzie, a na których muszę przekazać wywołania zwrotne, aby móc przetworzyć dane wyjściowe po zakończeniu operacji początkowej? Czy jest gdzieś lista funkcji JavaScript, które są asynchroniczne / nieblokujące, oraz lista funkcji synchronicznych / blokujących? Co sprawia, że ​​moja aplikacja Javascript nie jest jedną wielką rasą?

Wiem, że operacje, które zajmują dużo czasu, takie jak operacje We / Wy w operacjach Node i AJAX w Internecie, wymagają od nich asynchroniczności i dlatego wymagają wywołań zwrotnych - ale kto określa, co można uznać za „długi czas”? Czy istnieje jakiś wyzwalacz w tych operacjach, który usuwa je z normalnej „kolejki zdarzeń”? Jeśli nie, co odróżnia je od prostych operacji, takich jak przypisywanie wartości do zmiennych lub zapętlanie tablic, od których, jak się wydaje, możemy polegać na zakończeniu synchronicznym?

Być może nawet nie myślę o tym poprawnie - mam nadzieję, że ktoś mnie wyprostuje. Dzięki!


jest to coś, co uważam za bardzo przydatne, chociaż twoja odpowiedź na twoje pytanie jest taka, że ​​musisz sprawdzić dokumentację, aby dowiedzieć się, czy metody są asynchroniczne.
Anastasios Andronidis

Odpowiedzi:


13

Ogólnie rzecz biorąc, każda funkcja, która korzysta z sieci lub używa timerów do wykonywania zadań przez pewien czas, będzie asynchroniczna.

Jeśli funkcja odbiera wywołanie zwrotne, możesz sprawdzić, do czego służy wywołanie zwrotne, i zwykle będzie oczywiste, czy jest asynchroniczne, czy nie. Jeśli funkcja nie oferuje wywołania zwrotnego, oznacza to, że nie ma możliwości komunikowania wyników asynchronicznych, więc prawdopodobnie nie jest asynchroniczna.

Nie ma na pewno żelaznego sposobu, aby to stwierdzić. Musi to zostać określone w dokumencie dla funkcji lub oczywiste ze sposobu działania interfejsu.

Operacje asynchroniczne różnią się pod osłonami niż operacje synchroniczne, ponieważ operacje asynchroniczne mają na celu skonfigurowanie operacji, rozpoczęcie operacji, a następnie powiadomienie później o postępie, zakończeniu lub błędach w operacji. Iterowanie tablicy jest operacją synchroniczną. Nie ma żadnego z tych problemów. Kod działa tylko synchronicznie. Wywołanie wywołania ajax polega na zarejestrowaniu wywołania zwrotnego dla powiadomień o stanie, następnie uruchomieniu wywołania ajax, a następnie kontynuowaniu uruchamiania innego javascript, a następnie jakiś czas później wywołanie zwrotne jest wywoływane ze zmianą stanu wywołania ajax (np. Ukończeniem).


1
Dodatkowo, niektóre funkcje Javascript blokują i nie blokują, w zależności od ich parametrów. Na przykład XMLHttpRequest.openma asyncparametr boolowski , który kontroluje, czy późniejsze wywołanie sendjest asynchroniczne.
Brian

Po prostu nie znalazłem tej odpowiedzi pomocnej i ogólnie wyjaśnionej.
Mehdi Raash

@MehdiRaash - Odpowiedź jest taka, że ​​wymyślisz to na podstawie dokumentacji lub interfejsu. Nie ma innego wyjścia. Tak to mówi. Nie jestem pewien, czego jeszcze się spodziewałeś. Nie ma odpowiedzi na magiczną kulę.
jfriend00

6

Z tego, co rozumiem, nie pytasz o to , co powinieneś uczynić asynchronicznym, ale jak stwierdzić, czy funkcja jest asynchroniczna.

Sprawdzasz dokumentację. Poważnie - po to jest. Nie zgadujesz, co robi funkcja na podstawie jej nazwy lub jej kontekstu. Jeśli nie masz pewności i masz dostęp do jego kodu źródłowego, sprawdź to.

To jedyny całkowicie niezawodny sposób.

Teraz czas na oszacowanie.

  • Jeśli przyjmuje oddzwonienie lub zwraca obietnicę, prawdopodobnie jest asynchroniczny (widziałem wyjątki dla tej reguły)
  • Ogólnie wszystko, co dotyczy operacji we / wy w node.js i bardziej ogólnie w JavaScript, jest wykonywane asynchronicznie (widziałem też wyjątki od tej reguły)

4

Ponieważ JavaScript jest jednowątkowy, wszystkie bloki przetwarzania są przetwarzane do momentu wystąpienia jednego z poniższych zdarzeń

1) Bieżące wykonanie żąda usługi zewnętrznej, takiej jak żądanie We / Wy lub sieci, lub żądanie pracownika sieci

2) Wywołanie funkcji jest ustawiane na zegarze w celu wykonania w późniejszym czasie

Nie ma listy funkcji blokujących / nieblokujących. Powinieneś sprawdzić dokumentację.

Twoja aplikacja może napotkać warunek wyścigu, jeśli wiele zewnętrznych usług ma blokadę wątku javascript i spróbuje uzyskać do niego dostęp w tym samym czasie. Nowoczesne przeglądarki i silnik V8 radzą sobie z tym, ale możesz napotkać ten warunek wyścigu, jeśli używasz telefonu i piszesz aplikacje javascript na urządzenia mobilne. Wsparcie nie jest w stanie poradzić sobie w tych warunkach wyścigowych.

Zasadniczo zakładaj bloki kodu, chyba że istnieje wywołanie zwrotne. I nawet jeśli istnieje oddzwonienie, to nie znaczy, że nie będzie blokować.


-1

Ja też jestem nowy w node.js (i JavaScript w ogóle) i nie jestem przyzwyczajony do tak dużego kodu asynchronicznego. Chciałem tylko zauważyć , że w Omówieniu blokowania vs nieblokowania na stronie nodejs.org stwierdza się, że:

Wszystkie metody we / wy w standardowej bibliotece Node.js zapewniają wersje asynchroniczne, które nie są blokujące i akceptują funkcje zwrotne. Niektóre metody mają również blokujące odpowiedniki, których nazwy kończą się na Sync.


1
w jaki sposób rozwiązuje to pytanie? Zobacz, jak odpowiedzieć
komnata
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.