Tworzę konsolę podobną do skryptu na potrzeby osobiste. Muszę być w stanie wstrzymać się na dłuższy czas, ale z moich badań wynika, że node.js nie ma możliwości zatrzymania się zgodnie z wymaganiami. Po pewnym czasie trudno jest odczytać informacje o użytkownikach ... Widziałem trochę kodu, ale uważam, że muszą mieć w sobie inny kod, aby działały, takie jak:
setTimeout(function() {
}, 3000);
Potrzebuję jednak wszystkiego po tym wierszu kodu, aby wykonać po pewnym czasie.
Na przykład,
//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode.
Widziałem też takie rzeczy
yield sleep(2000);
Ale node.js tego nie rozpoznaje.
Jak mogę osiągnąć tę dłuższą przerwę?
javascript
node.js
yield
Christopher Allen
źródło
źródło
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Odpowiedzi:
Najlepszym sposobem na to jest podzielenie kodu na wiele funkcji, takich jak:
Jest podobny do rozwiązania JohnnyHK , ale o wiele ładniejszy i łatwiejszy do rozszerzenia.
źródło
debugger;
Nowa odpowiedź na stare pytanie. Dzisiaj (
styczeń 2017czerwca 2019) jest znacznie łatwiej. Możesz użyć nowejasync/await
składni . Na przykład:Aby używaćasync/await
od razu po instalacji bez instalacji i wtyczek, musisz użyć node-v7 lub node-v8, używając--harmony
flagi.Aktualizacja czerwca 2019 r .: Korzystając z najnowszych wersji NodeJS, możesz go używać od razu po wyjęciu z pudełka. Nie trzeba podawać argumentów wiersza poleceń. Nawet Google Chrome obsługuje go dzisiaj.
Aktualizacja maj 2020: wkrótce będzie można używać
await
składni poza funkcją asynchroniczną. Na najwyższym poziomie, jak w tym przykładzieWniosek znajduje się na etapie 3 . Możesz z niego korzystać dzisiaj, używając webpacka 5 (alfa),
Więcej informacji:
źródło
await
słowa kluczowego przedsleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Dla maniaków oneliner jak ja :)let sleep = require('util').promisify(setTimeout);
działa na węźle 7.6+ i poprawia czytelnośćNajkrótsze rozwiązanie bez żadnych zależności:
źródło
let sleep = require('util').promisify(setTimeout);
to trzy znaki dłuższe, ale wielokrotnego użytku i bardziej czytelne imoresolve
zamiast niejdone
. Czyliawait new Promise(resolve => setTimeout(resolve, 5000))
Wpisz kod, który chcesz wykonać po opóźnieniu w ciągu
setTimeout
wywołania zwrotnego:źródło
node-fibers
. Sprawdź to.Jest to prosta technika blokowania:
To blokowanie , o ile nic innego nie będzie się działo w skrypcie (jak wywołania zwrotne). Ale ponieważ jest to skrypt konsoli, być może jest to, czego potrzebujesz!
źródło
wait
, blokuje i działa w jakimś celu testowym. Dokładnie tego szukałem.spin-wait
.W węźle 7.6.0 lub nowszym
Węzeł obsługuje natywne oczekiwanie:
to jeśli możesz użyć funkcji asynchronicznych:
lub:
W starszych wersjach węzłów (oryginalna odpowiedź)
Chciałem asynchronicznego trybu uśpienia, który działał w systemach Windows i Linux, bez konieczności zapychania mojego procesora długą pętlą while. Próbowałem pakietu uśpienia, ale nie można go zainstalować na moim komputerze z systemem Windows. Skończyło się na tym, że:
https://www.npmjs.com/package/system-sleep
Aby go zainstalować, wpisz:
W twoim kodzie
Działa jak marzenie.
źródło
Prosta i elegancka funkcja snu z wykorzystaniem nowoczesnego Javascript
Bez zależności, bez piekła zwrotnego; Otóż to :-)
Biorąc pod uwagę przykład podany w pytaniu, w ten sposób chcielibyśmy spać między dwoma dziennikami konsoli:
„Wada” polega na tym, że teraz musi być
async
również twoja główna funkcja . Ale biorąc pod uwagę, że już piszesz nowoczesny kod JavaScript, prawdopodobnie (lub przynajmniej powinieneś!) Używaszasync
/await
całego kodu, więc to naprawdę nie jest problem. Wszystkie współczesne przeglądarki obsługują obecnie to.Dając trochę wglądu w
sleep
funkcję dla tych, którzy nie są przyzwyczajeniasync/await
i operatorzy grubych strzał, jest to pełny sposób pisania:Jednak użycie operatora grubych strzałek czyni go jeszcze mniejszym (i bardziej eleganckim).
źródło
async
i pozostawiając wszystko inne bez zmian. Prawdopodobnie jest to jednak wyraźniejszeasync
.async
. Edytowałem moją odpowiedź z twoją sugestią. Nie sądzę, żeby kod był bardziej przejrzysty; w tym celu skorzystałbym zamiast tego z JSDoc.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Możesz użyć tego www.npmjs.com/package/sleep
źródło
MacOS
, ale napotyka błędy zCentOS
powodu błędów node_gyp . Nie wydaje się przenośny.To pytanie jest dość stare, ale ostatnio V8 dodało Generatory, które mogą spełnić wymagania OP. Generatory są zazwyczaj najłatwiejsze w użyciu do interakcji asynchronicznych z pomocą biblioteki, takiej jak zawieszenie lub uruchomienie generatora .
Oto przykład użycia zawieszenia:
Literatura pokrewna (poprzez bezwstydną autopromocję): O co chodzi z generatorami? .
źródło
yield setTimeout(suspend.resume(), 10000);
--harmony
flagą i według node.green są przynajmniej dostępne bez żadnych flag od wersji v4.8.4: node.green/#ES2015-functions-generators-basic-functionality . Należy jednak pamiętać, że nowszaasync/await
składnia zapewnia teraz lepsze rozwiązanie tego problemu, bez potrzeby korzystania z dodatkowych bibliotek, takich jaksuspend
. Zobacz tę odpowiedź na przykład: stackoverflow.com/a/41957152/376789 . Funkcje asynchroniczne są dostępne (bez flag) od wersji 7.10.W systemie Linux / nodejs działa to dla mnie:
Blokuje, ale nie jest zajęta pętla oczekiwania.
Określony czas jest w sekundach, ale może być ułamkiem. Nie wiem, czy inne systemy operacyjne mają podobne polecenia.
źródło
sleep
jest prawie wszechobecny i jest wszechstronny od wczesnych dni UNIXa en.wikipedia.org/wiki/Sleep_%28Unix%29 . Tylko „nie rzadko” OS to może nie istnieć to okna (jednak nie można próbowaćchild_process.spawnSync('timeout', ['/T', '10'])
Jeśli chcesz „kodować golfa”, możesz utworzyć krótszą wersję niektórych innych odpowiedzi tutaj:
Ale naprawdę idealną odpowiedzią jest moim zdaniem użycie
util
biblioteki Node i jejpromisify
funkcji, która została zaprojektowana właśnie do tego rodzaju rzeczy (tworzenie opartych na obietnicach wersji wcześniej istniejących rzeczy nieobjętych obietnicą):W obu przypadkach można następnie wstrzymać, używając funkcji
await
wywoływaniasleep
:źródło
await
. W pewnym sensie tworzy wywołanie zwrotne, wstrzymuje rzeczy, a następnie ponownie uruchamia kod, gdy to wywołanie zwrotne powróci. Oddzwanianie powraca z wartością, ale w tym przypadku nie obchodzi nas to, więc nie ma nic po lewej stronieawait
.Niedawno stworzyłem prostszą abstrakcję o nazwie wait.for aby wywoływać funkcje asynchroniczne w trybie synchronizacji (na podstawie włókien węzłowych). Istnieje również wersja oparta na nadchodzących generatorach ES6.
https://github.com/luciotato/waitfor
Korzystanie z wait.for można wywoływać dowolną standardową funkcję asynchroniczną nodejs, tak jakby to była funkcja synchronizacji, bez blokowania pętli zdarzeń węzła.
Możesz kodować sekwencyjnie, kiedy jest to potrzebne, co jest (tak sądzę) idealne, aby uprościć skrypty do użytku osobistego.
za pomocą wait.for twój kod będzie:
W trybie synchronizacji można również wywołać dowolną funkcję asynchroniczną . Sprawdź przykłady.
źródło
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
napotkałem kolejne błędy związane z niezdefiniowanymi właściwościami itp. Więc musiałem je również skopiować. Dlaczego nie zorganizujesz kodu w taki sposób, aby nie był wymagany?Ponieważ silnik javascript (v8) uruchamia kod na podstawie sekwencji zdarzeń w kolejce zdarzeń, nie ma ścisłego wymogu, aby javascript dokładnie uruchamiał wykonywanie po określonym czasie. Oznacza to, że po ustawieniu kilku sekund na wykonanie kodu później kod wyzwalający opiera się wyłącznie na sekwencji w kolejce zdarzeń. Wywołanie wykonania kodu może więc zająć więcej niż określony czas.
Więc Node.js podąża
aby uruchomić kod później zamiast setTimeout (). Na przykład,
źródło
Dzięki obsłudze ES6
Promise
możemy z nich korzystać bez żadnej pomocy strony trzeciej.Następnie użyj go w następujący sposób:
Zauważ, że
doWhat
funkcja staje sięresolve
wywołaniem zwrotnym w obrębienew Promise(...)
.Zauważ też, że jest to sen ASYNCHRONICZNY. Nie blokuje pętli zdarzeń. Jeśli potrzebujesz blokowania snu, skorzystaj z tej biblioteki, która realizuje blokowanie snu za pomocą powiązań C ++. (Chociaż potrzeba blokowania snu w Węzłach, takich jak środowiska asynchroniczne, jest rzadka).
https://github.com/erikdubbelboer/node-sleep
źródło
Powyższy kod jest efektem ubocznym rozwiązania problemu asynchronicznego wywołania zwrotnego asynchronicznego kodu JavaScript. Jest to również powód, dla którego uważam, że JavaScript jest przydatnym językiem w backend. Moim zdaniem jest to najbardziej ekscytujące ulepszenie wprowadzone we współczesnym Javascript. Aby w pełni zrozumieć, jak to działa, należy w pełni zrozumieć sposób działania generatora. Słowo
function
kluczowe, po którym następuje a,*
nazywa się funkcją generatora we współczesnym Javascript. Pakiet npmco
funkcję Runner do uruchamiania generatora.Zasadniczo funkcja generatora zapewniła sposób na wstrzymanie wykonania funkcji ze
yield
słowem kluczowym, a jednocześnieyield
w funkcji generatora umożliwiła wymianę informacji między generatorem a dzwoniącym. Dało to mechanizmowi wywołującemu wyodrębnienie danych zpromise
połączenia asynchronicznego i przekazanie rozstrzygniętych danych z powrotem do generatora. Skutecznie sprawia, że połączenie asynchroniczne jest synchroniczne.źródło
Jest to moduł o smaku moment.js oparty na podejściu brudnego blokowania sugerowanym przez @ atlex2 . Używaj tego tylko do testowania .
źródło
Jeśli potrzebujesz tylko zawiesić w celu testowania, bieżące wykonanie wątku spróbuj:
źródło
po prostu poczekamy 5 sekund, aby zdarzyło się jakieś zdarzenie (byłoby to wskazane przez zrobioną zmienną ustawioną na true w innym miejscu w kodzie) lub gdy upłynie limit czasu, że sprawdzamy co 100 ms
źródło
Dla niektórych osób zaakceptowana odpowiedź nie działa, znalazłem inną odpowiedź i działa ona dla mnie: Jak mogę przekazać parametr do wywołania zwrotnego setTimeout ()?
„hello” jest przekazywanym parametrem, wszystkie parametry można przekazać po upływie limitu czasu. Dzięki @Fabio Phms za odpowiedź.
źródło
Zamiast robić wszystkie te setTimeout, spać i wiele innych rzeczy, lepiej użyć
źródło
Inne odpowiedzi są świetne, ale pomyślałem, że wybiorę inny takt.
Jeśli naprawdę szukasz jedynie spowolnienia określonego pliku w systemie Linux:
węzeł slowprile mójprog
Będzie to spało 1 sekundę co pięć linii. Program węzła będzie działał tak wolno, jak program piszący. Jeśli robi inne rzeczy, będą kontynuować z normalną prędkością.
Program mkfifo tworzy potok typu „pierwsze weszło, pierwsze wyszło”. To sprawia, że to działa. Linia perla napisze tak szybko, jak chcesz. $ | = 1 mówi, że nie buforuj danych wyjściowych.
źródło
Po przeczytaniu odpowiedzi na to pytanie stworzyłem prostą funkcję, która może również wykonać oddzwonienie, jeśli potrzebujesz:
źródło
Aby uzyskać więcej informacji na temat
powinieneś sprawdzić Redux-Saga . Ale jest to specyficzne dla twojego wyboru Redux jako modelu modelu (choć absolutnie nie jest to konieczne).
źródło