Jak Mogę Czekać W Node.js (Javascript), muszę wstrzymać się na pewien czas

Rozwijam skrypt podobny do konsoli dla osobistych potrzeb... Muszę być w stanie pauzować przez dłuższy czas, ale jako węzeł.js z moich badań nie ma sposobu, aby zatrzymać się zgodnie z wymaganiami.... Jego coraz trudno odczytać informacje użytkowników off po pewnym czasie... iv widziałem tam jakiś kod, ale wierzę, że muszą mieć inne kody w środku, aby działały, takie jak: {]}

setTimeout(function() {
}, 3000);

Ale ten problem polega na tym, że potrzebuję wszystkiego po tej linii kodu, aby wykonać po okresie czas...

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 jak

yield sleep(2000);
/ Align = "left" / js tego nie rozpoznaje.... Jeśli ktoś jest chętny do pomocy, jest to bardzo doceniane.
Author: Christopher Allen, 2013-01-10

23 answers

Najlepszym sposobem na to jest podział kodu na wiele funkcji, jak to:

function function1() {
    // stuff you want to happen right away
    console.log('Welcome to My Console,');
}

function function2() {
    // all the stuff you want to happen after that pause
    console.log('Blah blah blah blah extra-blah');
}

// call the first chunk of code right away
function1();

// call the rest of the code and have it execute after 3 seconds
setTimeout(function2, 3000);
Jest to rozwiązanie podobne do rozwiązania JohnnyHK, ale znacznie prostsze i łatwiejsze do rozszerzenia.
 118
Author: Elliot Bonneville,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-03 18:41:48

Umieść kod, który chcesz wykonać po opóźnieniu w setTimeout callback:

console.log('Welcome to My Console,');
setTimeout(function() {
    console.log('Blah blah blah blah extra-blah');
}, 3000);
 118
Author: JohnnyHK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-10 01:44:53

Nowa odpowiedź na Stare pytanie. Dzisiaj (Styczeń 2017) jest o wiele łatwiej. Możesz użyć składni new async/await . Na przykład:

async function init(){
   console.log(1)
   await sleep(1000)
   console.log(2)
}
function sleep(ms){
    return new Promise(resolve=>{
        setTimeout(resolve,ms)
    })
}

Aby używać async/await po wyjęciu z pudełka bez instalowania i wtyczek, musisz użyć node-v7 lub node-v8, używając znacznika --harmony.

Więcej informacji:

 115
Author: Aminadav Glickshtein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 20:38:29

Jest to prosta technika blokowania:

var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}

To blokowanie o ile nic innego nie stanie się w Twoim skrypcie (jak wywołania zwrotne). Ale ponieważ jest to skrypt konsoli, może to jest to, czego potrzebujesz!

 88
Author: atlex2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-01 17:51:08

Możesz użyć tego www.npmjs.com/package/sleep

var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds
 45
Author: Aleksej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 17:40:54

To pytanie jest dość stare, ale ostatnio V8 dodał Generatory, które mogą osiągnąć to, o co prosił OP. Generatory są na ogół najprostsze w użyciu do interakcji asynchronicznych z pomocą biblioteki, takiej jak suspend lub gen-run.

Oto przykład użycia suspend:

suspend(function* () {
    console.log('Welcome to My Console,');
    yield setTimeout(suspend.resume(), 10000); // 10 seconds pass..
    console.log('Blah blah blah blah extra-blah');
})();

Podobne czytanie (poprzez bezwstydną autopromocję): o co chodzi z generatorami?.

 33
Author: jmar777,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-23 05:32:59

Prosta i elegancka funkcja spania przy użyciu nowoczesnego Javascript

function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

Brak zależności, brak callback hell; to wszystko: -)


Biorąc pod uwagę przykład podany w pytaniu, tak czekalibyśmy między dwoma logami konsoli:

async function main() {
    console.log("Foo");
    await sleep(2000);
    console.log("Bar");
}

main();

"wadą" jest to, że Twoja główna funkcja musi być również async. Ale biorąc pod uwagę, że już piszesz nowoczesny kod Javascript, powinieneś używać async/await cały Twój kod, więc to naprawdę nie jest problem. Wszystkie nowoczesne przeglądarki dzisiaj obsługują to.

Dając trochę wgląd w funkcję sleep dla tych, które nie są używane do async/await, Możesz również napisać to tak:

async function sleep(millis) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () { resolve(); }, millis);
    });
}

Użycie operatora fat arrow sprawia jednak, że jest on jeszcze mniejszy (i bardziej elegancki).

 31
Author: Lucio Paiva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-20 14:33:29

Najkrótsze rozwiązanie bez żadnych zależności:

await new Promise(done => setTimeout(done, 5000));
 17
Author: k06a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-06 20:47:32

Ostatnio stworzyłem prostszą abstrakcję o nazwie czekaj.dla wywoływania funkcji asynchronicznych w trybie synchronizacji (w oparciu o node-fibers). Istnieje również wersja oparta na nadchodzących generatorach ES6.

Https://github.com/luciotato/waitfor

Using wait.dla , można wywołać dowolną standardową funkcję asynchroniczną nodejs, tak jakby była funkcją synchronizacji, bez blokowania pętli zdarzeń węzła.

Możesz kodować sekwencyjnie, kiedy tego potrzebujesz, co jest (zgaduję) idealne do uprość skrypty do użytku osobistego.

Using wait.dla twój kod będzie:

require('waitfor')

..in a fiber..
//start-of-code
console.log('Welcome to My Console,');
wait.miliseconds(10*1000); //defined in waitfor/paralell-tests.js - DOES NOT BLOCK
console.log('Blah blah blah blah extra-blah');
//endcode. 

Również każda funkcja asynchroniczna może być wywołana w trybie Sync. Sprawdź przykłady.

 13
Author: Lucio M. Tato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-06 13:58:46

Na Linuksie/nodejs to mi działa:

Const spawnSync = require ('child_process').spawnSync;

Var sleep = spawnSync ('sleep', [1.5]);

Blokuje, ale nie jest zajętą pętlą oczekiwania.

Podany czas jest w sekundach, ale może być ułamkiem. Nie wiem, czy inne OS mają podobną komendę.

 13
Author: Bart Verheijen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-18 18:50:04

Chciałem asynchronicznego snu, który działał w systemach Windows i Linux, bez blokowania mojego procesora długą pętlą while. Próbowałem pakietu sleep, ale nie instalował się na moim pudełku Windows. Skończyło się na używaniu:

Https://www.npmjs.com/package/system-sleep

Aby go zainstalować, wpisz:

npm install system-sleep

W Twoim kodzie,

var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds
Działa jak urok.
 11
Author: Ryan Shillington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-13 18:56:36

Jeśli chcesz "kodować golfa", możesz zrobić krótszą wersję niektórych innych odpowiedzi tutaj:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

Ale tak naprawdę idealną odpowiedzią moim zdaniem jest użycie biblioteki util Node i jej funkcji promisify, która jest zaprojektowana do tego typu rzeczy (Tworzenie wersji opartych na obietnicach wcześniej istniejących rzeczy nie opartych na obietnicach):

const util = require('util');
const sleep = util.promisify(setTimeout);

W obu przypadkach możesz wstrzymać po prostu za pomocą await, aby wywołać funkcję sleep:

await sleep(1000); // sleep for 1s/1000ms
 9
Author: machineghost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 00:38:40

Ponieważ silnik javascript (v8) uruchamia kod w oparciu o sekwencję zdarzeń w event-queue, nie ma ścisłego wymogu, aby javascript dokładnie wyzwalał wykonanie po określonym czasie. Oznacza to, że gdy ustawisz kilka sekund na późniejsze wykonanie kodu, Kod wyzwalający opiera się wyłącznie na sekwencji w kolejce zdarzeń. Uruchomienie wykonania kodu może więc zająć więcej niż określony czas.

So Node.js follows,

process.nextTick()

Aby uruchomić kod później zamiast setTimeout (). Na przykład,

process.nextTick(function(){
    console.log("This will be printed later");
});
 6
Author: HILARUDEEN ALLAUDEEN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-16 06:33:20

Z obsługą ES6 Promise s, możemy ich używać bez pomocy osób trzecich.

const sleep = (seconds) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, (seconds * 1000));
    });
};

// We are not using `reject` anywhere, but it is good to
// stick to standard signature.

Następnie użyj go tak:

const waitThenDo(howLong, doWhat) => {
    return sleep(howLong).then(doWhat);
};

Zauważ, że funkcja doWhat staje się wywołaniem zwrotnym resolve wewnątrz new Promise(...).

Zauważ również, że jest to asynchroniczny sen. Nie blokuje pętli zdarzeń. Jeśli chcesz zablokować sen, użyj tej biblioteki, która realizuje blokowanie snu za pomocą wiązań C++. (Chociaż potrzeba blokowania uśpienia w Node, takim jak środowiska asynchroniczne, jest Rzadki.)

Https://github.com/erikdubbelboer/node-sleep

 2
Author: treecoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-31 23:27:13
let co = require('co');
const sleep = ms => new Promise(res => setTimeout(res, ms));

co(function*() {
    console.log('Welcome to My Console,');
    yield sleep(3000);
    console.log('Blah blah blah blah extra-blah');
});

Powyższy kod jest efektem ubocznym rozwiązania asynchronicznego problemu wywołania zwrotnego Javascript. Jest to również powód, dla którego uważam, że Javascript jest użytecznym językiem w backendzie. W rzeczywistości jest to najbardziej ekscytujące ulepszenie wprowadzone do współczesnego Javascript moim zdaniem. Aby w pełni zrozumieć, jak to działa, należy w pełni zrozumieć sposób działania generatora. Słowo kluczowe function, po którym następuje *, jest nazywane funkcją generatora we współczesnym Javascript. Pakiet npm co dostarczono funkcję runner do uruchomienia generatora.

Zasadniczo funkcja generatora umożliwiała wstrzymanie wykonania funkcji za pomocą słowa kluczowego yield, jednocześnie yield w funkcji generatora umożliwiała wymianę informacji pomiędzy wewnątrz generatora a wywołującym. Dzięki temu wywołujący mógł wyodrębnić dane z promise z asynchronicznego wywołania i przekazać rozwiązane dane z powrotem do generatora. Skutecznie wykonuje asynchroniczne wywołanie synchroniczne.

 1
Author: Elgs Qian Chen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 11:57:52

Jeśli musisz tylko zawiesić w celu testowania, wykonaj bieżący wątek, spróbuj tego:

function longExecFunc(callback, count) {

    for (var j = 0; j < count; j++) {
        for (var i = 1; i < (1 << 30); i++) {
            var q = Math.sqrt(1 << 30);
        }
    }
    callback();
}
longExecFunc(() => { console.log('done!')}, 5); //5, 6 ... whatever. Higher -- longer
 0
Author: Ivan Talalaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-29 09:19:15

Proste będziemy czekać 5 sekund na jakieś zdarzenie (które będzie wskazywane przez zmienną done ustawioną na true gdzie indziej w kodzie) lub gdy timeout wygaśnie, że będziemy sprawdzać co 100ms

    var timeout=5000; //will wait for 5 seconds or untildone
    var scope = this; //bind this to scope variable
    (function() {
        if (timeout<=0 || scope.done) //timeout expired or done
        {
            scope.callback();//some function to call after we are done
        }
        else
        {
            setTimeout(arguments.callee,100) //call itself again until done
            timeout -= 100;
        }
    })();
 0
Author: Stan Sokolov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 14:54:04

Dla niektórych osób akceptowana odpowiedź nie działa, znalazłem inną odpowiedź i działa dla mnie: Jak mogę przekazać parametr do wywołania zwrotnego setTimeout ()?

var hello = "Hello World";
setTimeout(alert, 1000, hello); 

'hello' jest parametrem przekazywanym, możesz przekazać wszystkie parametry po upływie czasu timeout. Dzięki @ Fabio Phms za odpowiedź.

 0
Author: Dazt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:24

Zobacz readline-sync ( https://www.npmjs.com/package/readline-sync )

Zainstaluj za pomocą npm install readline-sync

var readlineSync = require('readline-sync');
while(true) {
  var input = readlineSync.question("What is your input?");
  if(input === 'exit') {
    process.exit();
  } else {
    console.log("Your input was " + input);
  }
}

Może nie najlepsza praktyka, ale robi to za mnie

 0
Author: MonoThreaded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-26 22:01:46

To jest chwila.moduł js oparty na podejściu dirty blocking sugerowanym przez @atlex2 . Użyj tego tylko do testów .

const moment = require('moment');

let sleep = (secondsToSleep = 1) => {
    let sleepUntill = moment().add(secondsToSleep, 'seconds');
    while(moment().isBefore(sleepUntill)) { /* block the process */ }
}

module.exports = sleep;
 0
Author: Boaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-08 14:11:34

Inne odpowiedzi są świetne, ale pomyślałem, że wezmę inny takt.

Jeśli wszystko czego naprawdę szukasz to spowolnienie konkretnego pliku w Linuksie:

 rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile  &

Node myprog slowfile

To będzie spać 1 sek co pięć linii. Program node będzie działał tak wolno jak writer. Jeśli robi inne rzeczy, będą kontynuować z normalną prędkością.

Mkfifo tworzy rurę typu first-in-first-out. To sprawia, że to działa. Linia Perla będzie pisać tak szybko, jak chcesz. $ / =1 mówi: nie buforuj wyjścia.
 -1
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-05 14:24:14

Aby uzyskać więcej informacji na temat

yield sleep(2000); 

Powinieneś sprawdzić Redux-Saga . Ale jest to specyficzne dla Twojego wyboru Redux jako ramy modelu (chociaż absolutnie nie jest to konieczne).

 -2
Author: Arseni Buinitski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-09 09:24:46

Ułożyłem, po przeczytaniu odpowiedzi na to pytanie, prostą funkcję, która może również zrobić callback, jeśli potrzebujesz, że:

function waitFor(ms, cb) {
  var waitTill = new Date(new Date().getTime() + ms);
  while(waitTill > new Date()){};
  if (cb) {
    cb()
  } else {
   return true
  }
}
 -2
Author: Netsi1964,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-06 08:08:38