Wydaje mi się, że po wykonaniu znajduje się w kolejce, ale czy w kolejce jest jakaś pewność, że wywoła się dokładnie po X milisekundach? A może inne ciężkie zadania znajdujące się wyżej w kolejce opóźnią to?
javascript
node.js
serverside-javascript
MyCodeGone
źródło
źródło
Odpowiedzi:
Semantyka setTimeout jest mniej więcej taka sama jak w przeglądarce internetowej: argument timeout to minimalna liczba ms oczekiwania przed wykonaniem, a nie gwarancja. Ponadto przekazanie 0, liczby innej niż liczba lub liczby ujemnej spowoduje, że zaczeka minimalną liczbę ms. W Node jest to 1 ms, ale w przeglądarkach może to być nawet 50 ms.
Powodem tego jest brak wywłaszczania JavaScript przez JavaScript. Rozważmy ten przykład:
Przepływ tutaj jest:
Gdyby tak nie było, można by jeden kawałek JavaScript „przerywać” inny. Musielibyśmy ustawić muteksy, semafory i tym podobne, aby kod taki jak ten nie był niezwykle trudny do rozważenia:
Jednowątkowość wykonywania JavaScript w Node sprawia, że praca z nim jest znacznie prostsza niż w przypadku większości innych stylów współbieżności. Oczywiście kompromis polega na tym, że źle działająca część programu może zablokować całość nieskończoną pętlą.
Czy to lepszy demon do walki niż złożoność wyprzedzania? To zależy.
źródło
console.log
wiadomość.Ideą nieblokowania jest to, że iteracje pętli są szybkie. Tak więc iteracja dla każdego taktu powinna zająć wystarczająco dużo czasu, aby setTimeout był dokładny z rozsądną precyzją (może być wyłączony o mniej niż 100 ms).
Teoretycznie jednak masz rację. Jeśli napiszę aplikację i zablokuję tick, to setTimeouts będzie opóźnione. Odpowiadając na pytanie, kto może zapewnić wykonanie setTimeouts na czas? Pisząc kod nieblokujący, możesz kontrolować stopień dokładności do prawie każdego rozsądnego poziomu dokładności.
Tak długo, jak javascript jest „jednowątkowy” pod względem wykonywania kodu (z wyłączeniem programów webowych i tym podobnych), zawsze tak się dzieje. Jednowątkowy charakter w większości przypadków jest ogromnym uproszczeniem, ale wymaga nieblokującego idiomu, aby odnieść sukces.
Wypróbuj ten kod w przeglądarce lub w węźle, a zobaczysz, że nie ma gwarancji dokładności, wręcz przeciwnie, setTimeout będzie bardzo późny:
O ile interpreter nie zoptymalizuje pętli (czego nie robi w chrome), otrzymasz coś w tysiącach. Usuń pętlę, a zobaczysz, że na nosie jest 500 ...
źródło
Jedynym sposobem zapewnienia wykonania kodu jest umieszczenie logiki setTimeout w innym procesie.
Użyj modułu procesu potomnego, aby stworzyć nowy program node.js, który wykonuje logikę i przekazuje dane do tego procesu za pośrednictwem pewnego rodzaju strumienia (może tcp).
W ten sposób, nawet jeśli jakiś długi kod blokujący jest uruchomiony w twoim głównym procesie, twój proces potomny już się rozpoczął i umieścił setTimeout w nowym procesie i nowym wątku, a zatem będzie działał, kiedy tego oczekujesz.
Dalsze komplikacje występują na poziomie sprzętowym, na którym działa więcej wątków niż procesów, a zatem przełączanie kontekstu spowoduje (bardzo niewielkie) opóźnienia w stosunku do oczekiwanego czasu. Powinno to być pomijalne, a jeśli ma to znaczenie, musisz poważnie rozważyć, co próbujesz zrobić, dlaczego potrzebujesz takiej dokładności i jakiego rodzaju alternatywny sprzęt czasu rzeczywistego jest dostępny do wykonania zadania.
Ogólnie rzecz biorąc, używanie procesów podrzędnych i uruchamianie aplikacji z wieloma węzłami jako oddzielnych procesów wraz z modułem równoważenia obciążenia lub współdzielonym magazynem danych (np. Redis) jest ważne dla skalowania kodu.
źródło
setTimeout
jest rodzajem wątku , przechowuje operację przez określony czas i wykonuje ją.w tym przypadku pierwszy argument powinien być typem funkcji; jako przykład, jeśli chcesz wydrukować swoje imię po 3 sekundach, kod powinien wyglądać jak poniżej.
Kluczową kwestią do zapamiętania jest to, co kiedykolwiek chcesz zrobić za pomocą
setTimeout
metody, zrób to wewnątrz funkcji . Jeśli chcesz wywołać inną metodę, analizując niektóre parametry, Twój kod powinien wyglądać jak poniżej:źródło
setTimeout(callback,t)
służy do wywołania zwrotnego po co najmniej t milisekundach . Rzeczywiste opóźnienie zależy od wielu czynników zewnętrznych, takich jak szczegółowość timera systemu operacyjnego i obciążenie systemu.Istnieje więc możliwość, że zostanie wywołany nieco po ustalonym czasie, ale nigdy wcześniej nie zostanie wywołany.
źródło