Czy jest lepszy sposób na inżynierię sleep
w JavaScript niż następująca pausecomp
funkcja ( wzięta stąd )?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
To nie jest kopia Sleep w JavaScript - opóźnienie między czynnościami ; Chcę prawdziwego snu w środku funkcji, a nie opóźnienia przed wykonaniem fragmentu kodu.
javascript
sleep
fmsf
źródło
źródło
Odpowiedzi:
Aktualizacja 2017-2019
Od 2009 roku, kiedy zadano to pytanie, JavaScript ewoluował znacznie. Wszystkie pozostałe odpowiedzi są teraz przestarzałe lub nadmiernie skomplikowane. Oto obecna najlepsza praktyka:
To jest to.
await sleep(<duration>)
.Lub jako jedna linijka:
Zauważ, że
await
może być wykonywany tylko w funkcjach poprzedzonychasync
słowem kluczowym lub na najwyższym poziomie skryptu w niektórych środowiskach (np. konsola Chrome DevTools lub Runkit).await
wstrzymuje tylko bieżącąasync
funkcjęDwie nowe funkcje JavaScript pomogły napisać tę funkcję „uśpienia”:
async/await
funkcja pozwala kodowi jawnie czekać na obietnicę do rozliczenia (rozstrzygnięcia lub odrzucenia).Zgodność
async
/await
wylądował w wersji 8 i został domyślnie włączony od Chrome 55 (wydany w grudniu 2016 r.)Jeśli z jakiegoś dziwnego powodu używasz Węzła starszego niż 7 (który osiągnął koniec życia ) lub celujesz w stare przeglądarki,
async
/await
nadal możesz go używać za pośrednictwem Babel (narzędzie, które przetłumaczy JavaScript + nowe funkcje na zwykły stary JavaScript) , ztransform-async-to-generator
wtyczką.źródło
(Zobacz zaktualizowaną odpowiedź na 2016 r. )
Myślę, że jest całkowicie rozsądne chcieć wykonać akcję, poczekać, a następnie wykonać inną akcję. Jeśli jesteś przyzwyczajony do pisania w językach wielowątkowych, prawdopodobnie masz pomysł na wykonanie przez określony czas, dopóki wątek się nie obudzi.
Problem polega na tym, że JavaScript jest modelem jednowątkowym opartym na zdarzeniach. Podczas gdy w konkretnym przypadku fajnie byłoby poczekać cały silnik na kilka sekund, ogólnie jest to zła praktyka. Załóżmy, że chciałem skorzystać z twoich funkcji podczas pisania własnych? Gdy wywołałem twoją metodę, wszystkie moje metody się zawiesiły. Jeśli JavaScript mógłby w jakiś sposób zachować kontekst wykonania twojej funkcji, zapisz ją gdzieś, a następnie przywróć i kontynuuj później, wtedy sen może się zdarzyć, ale to w zasadzie wątek.
Więc utknąłeś z tym, co sugerowali inni - musisz podzielić kod na wiele funkcji.
Twoje pytanie jest więc trochę fałszywym wyborem. Nie ma sposobu na spanie tak, jak chcesz, ani nie powinieneś szukać proponowanego rozwiązania.
źródło
sleep()
nie jest to możliwe w JS i że w większości przypadków są lepsze sposoby na robienie rzeczy. Ale nadal uważam sposób, w jaki silnik łączy wszystkie rzeczy, jako wadę projektową; nie ma powodu, dla którego język nie mógłby miećsleep()
funkcji ograniczonej do określonego skryptu, strony lub funkcji bez silnika blokującego procesor i zamrażającego aplikację jak maniak. Jest rok 2015 i nie powinieneś mieć możliwości awarii całej przeglądarki internetowejwhile(1)
. Mamy Flash do takich rzeczy.W JavaScript, przepisuję każdą funkcję, aby mogła zakończyć się jak najszybciej. Chcesz przywrócić kontrolę nad przeglądarką, aby mogła wprowadzać zmiany w DOM.
Za każdym razem, gdy chciałem spać w środku mojej funkcji, refaktoryzowałem użycie
setTimeout()
.Edytować
Niesławna funkcja snu lub opóźnienia w dowolnym języku jest przedmiotem wielu dyskusji. Niektórzy powiedzą, że zawsze powinien być sygnał lub oddzwonienie, aby uruchomić daną funkcjonalność, inni twierdzą, że czasami przydatny jest dowolny moment opóźnienia. Mówię, że każdemu ich własna i jedna zasada nigdy nie może dyktować niczego w tej branży.
Pisanie funkcji uśpienia jest proste i jeszcze bardziej użyteczne dzięki skryptom JavaScript:
źródło
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
Tylko dla debugowania / tworzenia , publikuję to, jeśli jest to przydatne dla kogoś
Ciekawe rzeczy, we Firebug (i prawdopodobnie innych konsolach js) nic się nie dzieje po wciśnięciu Enter, tylko po określonym czasie snu (...)
Przykład zastosowania:
źródło
only for debug/dev
... rolleyesZgadzam się z innymi plakatami, zajęty sen to po prostu zły pomysł.
Jednak setTimeout nie wstrzymuje wykonania, wykonuje następny wiersz funkcji natychmiast po ustawieniu limitu czasu, a nie po upływie limitu czasu, aby nie wykonać tego samego zadania, które wykonałby sen.
Sposobem na to jest podzielenie funkcji na części przed i po części.
Upewnij się, że nazwy funkcji nadal dokładnie opisują, co robi każdy element (IE GatherInputThenWait i CheckInput, a nie funcPart1 i funcPart2)
Edytować
Ta metoda osiąga cel polegający na tym, że nie wykonuje wierszy kodu, które zdecydujesz do momentu PO przekroczeniu limitu czasu, jednocześnie zwracając kontrolę z powrotem do komputera klienckiego, aby wykonać wszystko, co ustawiło w kolejce.
Dalsza edycja
Jak wskazano w komentarzach, absolutnie NIE zadziała to w pętli. Możesz zrobić fantazyjne (brzydkie) hakowanie, aby działało w pętli, ale ogólnie rzecz biorąc, spowoduje to katastrofalny kod spaghetti.
źródło
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
ifor(var X = 0; X < 3;X++) { foo(X); }
- przekazywana jest wartość Xfoo
, która następnie zostaje ponownie użyta pod nazwą,index
gdyfoo_continue
zostanie ostatecznie wywołana.console.log()
wnętrzefoo_continue()
w wersji setTimeout, a otrzymasz ten sam wynik.Z miłości do $ DEITY proszę nie robić funkcji spania z czekaniem.
setTimeout
isetInterval
rób wszystko, czego potrzebujesz.Co dwie sekundy interwał ukrywa tekst na jedną sekundę. To pokazuje, jak używać setInterval i setTimeout do pokazywania i ukrywania tekstu co sekundę.
źródło
Wiem, że to trochę stare pytanie, ale jeśli (podobnie jak ja) używasz Javascript z Rhino, możesz użyć ...
źródło
Jeśli używasz jQuery, ktoś faktycznie stworzył wtyczkę „opóźniającą”, która jest niczym więcej niż opakowaniem dla setTimeout:
Następnie możesz po prostu użyć go w szeregu wywołań funkcji zgodnie z oczekiwaniami:
źródło
.delay()
jest częścią jQuery (choć z semantyką inną niż powyższa implementacja). api.jquery.com/delayJa też szukałem rozwiązania uśpienia (nie kodu produkcyjnego, tylko Dev / Testy) i znalazłem ten artykuł:
http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html
... a oto kolejny link do rozwiązań po stronie klienta: http://www.devcheater.com/
Ponadto, gdy dzwonisz
alert()
, Twój kod również zostanie wstrzymany, gdy wyświetlany jest alert - musisz znaleźć sposób, aby nie wyświetlać alertu, ale uzyskać ten sam efekt. :)źródło
Oto proste rozwiązanie wykorzystujące synchroniczny XMLHttpRequest:
zawartość sleep.php:
Teraz nazwij to: sleep (5);
źródło
setTimeout()
jeśli to działa, ale jeśli to oznacza rozwikłanie 1000 linii zwrotnych, może to nie wyglądać jak żart.sleep(300)
i witryna potrzebuje 150 ms na odpowiedź, to kod javascript będzie spał przez 450ms. a jeśli połączenie internetowe zostanie utracone przez przeglądarkę, będzie działać tylko przez 0 ms. Więc to nie jest lepsze rozwiązanieProszę bardzo. Jak mówi kod, nie bądź złym deweloperem i używaj tego na stronach internetowych. Jest to funkcja narzędzia programistycznego.
źródło
async/await
niestety nie reaguje i musimy go obowiązkowo stosować.Osobiście podoba mi się prosty:
następnie:
Cały czas używam go do tworzenia fałszywego czasu ładowania podczas tworzenia skryptów w P5js
źródło
Pierwszy:
Zdefiniuj funkcję, którą chcesz wykonać w następujący sposób:
Następnie zaplanuj jego wykonanie za pomocą metody setTimeout:
Zwróć uwagę na dwie rzeczy
źródło
Lepszym rozwiązaniem, aby wyglądało tak, jak chce większość ludzi, jest skorzystanie z anonimowej funkcji:
Jest to prawdopodobnie najbliższe osiągnięcie czegoś, co po prostu robi, co chcesz.
Uwaga: jeśli potrzebujesz wielu snu, może to być brzydkie w pośpiechu i może być konieczne ponowne przemyślenie projektu.
źródło
upewnij się, że funkcja wywoływania jest asynchroniczna
sprawdzone i działa dobrze
źródło
W przypadku przeglądarek zgadzam się, że setTimeout i setInterval są właściwą drogą.
Ale w przypadku kodu po stronie serwera może to wymagać funkcji blokowania (na przykład w celu efektywnej synchronizacji wątków).
Jeśli używasz node.js i meteor, być może natrafiłeś na ograniczenia związane z używaniem setTimeout we włóknie. Oto kod uśpienia po stronie serwera.
Zobacz: https://github.com/laverdet/node-fibers#sleep
źródło
Server may require a blocking function
... Nie wiem, jak mocno blokuje jedyny wątek Node i sprawia, że cały serwerChciałbym zawrzeć setTimeOut w obietnicy zgodności kodu z innymi zadaniami asynchronicznymi: Demo w skrzypcach
Używany w ten sposób:
Łatwo zapamiętać składnię, jeśli używałeś obietnic.
źródło
Aktualizacja 2019 za pomocą Atomics.wait
Powinien działać w węźle 9.3 lub nowszym.
Potrzebowałem bardzo dokładnego timera w Node.js i działa świetnie do tego. Wydaje się jednak, że obsługa przeglądarek jest bardzo ograniczona.
Przebiegł kilka 10-sekundowych testów czasowych.
Dzięki setTimeout pojawia się błąd do 7000 mikrosekund. (7ms)
W przypadku Atomics mój błąd wydaje się utrzymywać poniżej 600 mikrosekund. (0,6 ms)
Aktualizacja 2020: Podsumowanie
z których np.
sleep.jsp
wygląda strona po stronie serweraźródło
Większość odpowiedzi tutaj jest błędnych lub przynajmniej nieaktualnych. Nie ma powodu, dla którego javascript musi być jednowątkowy, a tak nie jest. Obecnie wszystkie przeglądarki głównego nurtu obsługują pracowników, wcześniej inne środowiska wykonawcze javascript, takie jak Rhino i Node.js, obsługiwały wielowątkowość.
„Javascript jest jednowątkowy” nie jest prawidłową odpowiedzią. Na przykład uruchomienie funkcji uśpienia w ramach procesu roboczego nie zablokuje żadnego kodu działającego w wątku interfejsu użytkownika.
W nowszych środowiskach wykonawczych obsługujących generatory i wydajność można by wprowadzić podobną funkcjonalność do funkcji uśpienia w środowisku z jednym wątkiem:
Ta imitacja snu różni się od prawdziwej funkcji snu, ponieważ nie blokuje wątku. Jest to po prostu cukier nad bieżącą funkcją setTimeout javascript. Ten typ funkcjonalności został zaimplementowany w Task.js i powinien działać dzisiaj w Firefox.
źródło
sleep
przy użyciu wielu pracowników. Jeśli używasz Node.js, funkcje generatora są już zaimplementowane i mogą być używane zgodnie z opisem. Przeglądarki głównego nurtu nie mają na dzień dzisiejszy generatorów.Przeszukałem / przeszukałem sporo stron internetowych na javascript sleep / wait ... i nie ma odpowiedzi, jeśli chcesz javascript do „URUCHAMIANIE, OPÓŹNIENIE, URUCHAMIANIE” ... to, co większość ludzi ma, to: „URUCHAMIANIE, URUCHAMIANIE (bezużyteczne) rzeczy), RUN ”lub„ RUN, RUN + opóźniony RUN ”....
Więc zjadłem kilka hamburgerów i pomyślałem ::: oto rozwiązanie, które działa ... ale musisz pokroić działające kody ... ::: tak, wiem, to jest po prostu łatwiejsze do odczytania refaktoryzacja .. . nadal...
//......................................... //Przykład 1:
// .................................... // example2:
// ................. przykład3:
// .............. przykład4:
źródło
źródło
Najkrótsze rozwiązanie bez żadnych zależności:
źródło
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
W JavaScript nie można tak spać, a raczej nie powinieneś. Uruchomienie pętli uśpienia lub chwili spowoduje zawieszenie przeglądarki użytkownika do momentu zakończenia pętli.
Użyj licznika czasu określonego w odnośniku, do którego się odwołujesz.
źródło
Jednym ze scenariuszy, w których możesz chcieć skorzystać z funkcji sleep () zamiast z setTimeout (), jest to, że masz funkcję odpowiadającą na kliknięcie użytkownika, która ostatecznie otworzy nowe, tj. Wyskakujące okno i zainicjujesz pewne przetwarzanie, które wymaga krótkiego okresu do wykonania przed wyświetleniem wyskakującego okienka. Przesunięcie otwartego okna do zamknięcia oznacza, że przeglądarka zwykle blokuje je.
źródło
Rozumiem cel funkcji uśpienia, jeśli masz do czynienia z wykonywaniem synchronicznym. Funkcje setInterval i setTimeout tworzą równoległy wątek wykonania, który zwraca sekwencję wykonywania z powrotem do programu głównego, co jest nieskuteczne, jeśli trzeba czekać na dany wynik. Oczywiście można używać zdarzeń i procedur obsługi, ale w niektórych przypadkach nie jest to zamierzone.
źródło
Dodanie moich dwóch bitów. Potrzebowałem czasu oczekiwania na testy. Nie chciałem dzielić kodu, ponieważ byłoby to dużo pracy, więc dla mnie było to proste.
Nie widzę w tym żadnych wad i to załatwiło sprawę.
źródło
for
pętli prawie zawsze będzie wykonywane natychmiast, niezależnie od maksymalnej wartościi
, a nawet ze złożonym kodem matematycznym umieszczonym w środku. Tak więc, chyba że czekasz tylko kilka milisekund, nadal nie ma sposobu na spanie z wdziękiem w JS.Można to zrobić przy użyciu metody uśpienia Java. Przetestowałem to w FF i IE i nie blokuje komputera, nie żuje zasobów ani nie powoduje niekończących się uderzeń serwera. Wydaje mi się to czystym rozwiązaniem.
Najpierw musisz załadować Javę na stronę i udostępnić jej metody. Aby to zrobić, zrobiłem to:
Następnie wszystko, co musisz zrobić, aby uzyskać bezbolesną przerwę w JS, to:
Gdzie xxx to czas w milisekundach. W moim przypadku (dla uzasadnienia) była to część realizacji zamówienia zaplecza w bardzo małej firmie i musiałem wydrukować fakturę, którą trzeba było załadować z serwera. Zrobiłem to, ładując fakturę (jako stronę internetową) do ramki iFrame, a następnie drukując ramkę. Oczywiście musiałem poczekać, aż strona zostanie w pełni załadowana, zanim będę mógł wydrukować, więc JS musiał się zatrzymać. Osiągnąłem to, zmieniając ukryte pole formularza na stronie nadrzędnej za pomocą zdarzenia onLoad na stronie faktury (w ramce iFrame). A kod na stronie nadrzędnej do wydrukowania faktury wyglądał następująco (nieistotne części wycięte dla zachowania przejrzystości):
Tak więc użytkownik naciska przycisk, skrypt ładuje stronę faktury, a następnie czeka, sprawdzając co kwadrans, czy strona faktury jest ładowana, a następnie wyświetla okno dialogowe drukowania, aby użytkownik mógł wysłać ją do drukarki. CO BYŁO DO OKAZANIA.
źródło
Wiele odpowiedzi nie odpowiada (bezpośrednio) na pytanie, podobnie jak to ...
Oto moje dwa centy (lub funkcje):
Jeśli chcesz mniej nieporęcznych funkcji niż
setTimeout
isetInterval
, możesz zawinąć je w funkcje, które po prostu odwracają kolejność argumentów i nadają im ładne nazwy:Wersje CoffeeScript:
Następnie możesz ich ładnie używać z anonimowymi funkcjami:
Teraz można go łatwo odczytać jako „po N milisekundach ...” (lub „co N milisekund ...”)
źródło
W konkretnym przypadku, gdy chcesz rozdzielić zestaw wywołań wykonywanych przez pętlę, możesz użyć czegoś takiego jak poniższy kod z prototypem. Bez prototypu można zastąpić funkcję opóźnienia setTimeout.
źródło
Jeśli korzystasz z node.js, możesz rzucić okiem na włókna - natywne rozszerzenie C do węzła, rodzaj symulacji wielowątkowej.
Pozwala to robić prawdziwe
sleep
w sposób, który blokuje wykonanie we włóknie, ale nie blokuje w głównym wątku i innych włóknach.Oto przykład z własnego pliku Readme:
- a wyniki są:
źródło