Ich entwickle ein konsolenähnliches Skript für persönliche Bedürfnisse. Ich muss in der Lage sein, längere Zeit zu pausieren, aber nach meinen Recherchen kann node.js nicht wie erforderlich anhalten. Es wird nach einiger Zeit schwierig, Benutzerinformationen zu lesen ... Ich habe dort draußen Code gesehen, aber ich glaube, sie müssen anderen Code in sich haben, damit sie funktionieren, wie zum Beispiel:
setTimeout(function() {
}, 3000);
Ich brauche jedoch alles nach dieser Codezeile, um nach Ablauf der Zeit ausgeführt zu werden.
Zum Beispiel,
//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.
Ich habe auch Dinge wie gesehen
yield sleep(2000);
Aber node.js erkennt dies nicht.
Wie kann ich diese längere Pause erreichen?
javascript
node.js
yield
Christopher Allen
quelle
quelle
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Antworten:
Der beste Weg, dies zu tun, besteht darin, Ihren Code in mehrere Funktionen zu unterteilen, wie folgt:
Es ähnelt der Lösung von JohnnyHK , ist jedoch viel übersichtlicher und einfacher zu erweitern.
quelle
debugger;
Eine neue Antwort auf eine alte Frage. Heute (
Januar 2017,Juni 2019) ist es viel einfacher. Sie können die neueasync/await
Syntax verwenden . Zum Beispiel:Für dieasync/await
sofortige Verwendung ohne Installation und Plugins müssen Sie Node-v7 oder Node-v8 mit dem--harmony
Flag verwenden.Update Juni 2019: Mit den neuesten Versionen von NodeJS können Sie es sofort verwenden. Es müssen keine Befehlszeilenargumente angegeben werden. Sogar Google Chrome unterstützt es heute.
Update Mai 2020: In Kürze können Sie die
await
Syntax auch außerhalb einer asynchronen Funktion verwenden. In der obersten Ebene wie in diesem BeispielDer Vorschlag befindet sich in Phase 3 . Sie können es heute mit Webpack 5 (Alpha) verwenden.
Mehr Info:
quelle
await
Schlüsselwort vorsleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Für Oneliner-Freaks wie mich :)let sleep = require('util').promisify(setTimeout);
funktioniert auf Node 7.6+ und verbessert die LesbarkeitDie kürzeste Lösung ohne Abhängigkeiten:
quelle
let sleep = require('util').promisify(setTimeout);
ist drei Zeichen länger, aber wiederverwendbar und besser lesbar imoresolve
stattdessen andone
. Dhawait new Promise(resolve => setTimeout(resolve, 5000))
Fügen Sie den Code, den Sie nach der Verzögerung ausführen möchten, in den
setTimeout
Rückruf ein:quelle
node-fibers
. Hör zu.Dies ist eine einfache Blockiertechnik:
Es wird blockiert, sofern in Ihrem Skript nichts anderes passiert (wie Rückrufe). Aber da dies ein Konsolenskript ist, ist es vielleicht das, was Sie brauchen!
quelle
wait
, es blockiert und es funktioniert für einen Testzweck. Genau das, wonach ich gesucht habe.spin-wait
.Auf Knoten 7.6.0 oder höher
Der Knoten unterstützt das native Warten:
Wenn Sie dann asynchrone Funktionen verwenden können:
oder:
Auf älteren Node-Versionen (ursprüngliche Antwort)
Ich wollte einen asynchronen Ruhezustand, der unter Windows und Linux funktioniert, ohne meine CPU mit einer langen while-Schleife zu belasten. Ich habe das Schlafpaket ausprobiert, es wurde jedoch nicht auf meiner Windows-Box installiert. Am Ende habe ich verwendet:
https://www.npmjs.com/package/system-sleep
Geben Sie zum Installieren Folgendes ein:
In Ihrem Code
Klappt wunderbar.
quelle
Einfache und elegante Schlaffunktion mit modernem Javascript
Keine Abhängigkeiten, keine Rückrufhölle; das ist es :-)
In Anbetracht des in der Frage angegebenen Beispiels würden wir auf folgende Weise zwischen zwei Konsolenprotokollen schlafen:
Der "Nachteil" ist, dass Ihre Hauptfunktion jetzt auch sein muss
async
. Aber, wenn man bedenken Sie bereits modernen Javascript - Code schreiben, sind Sie wahrscheinlich (oder zumindest sollte es sein!) Mitasync
/ amawait
ganzen Code, so ist dies nicht wirklich ein Problem. Alle modernen Browser unterstützen dies heute.Dies ist die ausführliche Schreibweise, um einen kleinen Einblick in die
sleep
Funktion für diejenigen zu geben, die nicht daran gewöhnt sind,async/await
und Fettpfeiloperatoren:Die Verwendung des Fettpfeil-Operators macht ihn jedoch noch kleiner (und eleganter).
quelle
async
und alles andere gleich lassen. Es ist wahrscheinlich klarer mit demasync
obwohl.async
. Ich habe meine Antwort mit Ihrem Vorschlag bearbeitet. Ich denke nicht, dass es den Code klarer macht; Dafür würde ich stattdessen auf JSDoc zurückgreifen.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Sie können diese www.npmjs.com/package/sleep verwenden
quelle
MacOS
, aber es treten FehlerCentOS
aufgrund von node_gyp-Fehlern auf . Es scheint nicht tragbar.Diese Frage ist ziemlich alt, aber kürzlich hat V8 Generatoren hinzugefügt, die das erreichen können, was das OP angefordert hat. Generatoren sind im Allgemeinen am einfachsten für asynchrone Interaktionen mit Hilfe einer Bibliothek wie Suspend oder Gen-Run zu verwenden .
Hier ist ein Beispiel mit suspend:
Verwandte Lektüre (durch schamlose Eigenwerbung): Was ist die große Sache mit Generatoren? .
quelle
yield setTimeout(suspend.resume(), 10000);
--harmony
Flagge, und laut node.green sind sie seit Version 4.8.4 zumindest ohne Flaggen verfügbar: node.green/#ES2015-functions-generators-basic-functionality . Bitte beachten Sie jedoch, dass die neuereasync/await
Syntax jetzt eine bessere Lösung dafür bietet, ohne dass zusätzliche Bibliotheken wie erforderlich sindsuspend
. In dieser Antwort finden Sie ein Beispiel: stackoverflow.com/a/41957152/376789 . Async-Funktionen sind seit Version 7.10 verfügbar (ohne Flags).Unter Linux / nodejs funktioniert das bei mir:
Es blockiert, ist aber keine ausgelastete Warteschleife.
Die von Ihnen angegebene Zeit ist in Sekunden angegeben, kann jedoch ein Bruchteil sein. Ich weiß nicht, ob andere Betriebssysteme einen ähnlichen Befehl haben.
quelle
sleep
ist so ziemlich allgegenwärtig und seit den frühen UNIX-Tagen ein nützlicher Ort . en.wikipedia.org/wiki/Sleep_%28Unix%29 . Nur "nicht selten", wie es vielleicht nicht existieren würde, sind Fenster (wie auch immer Sie es versuchen könntenchild_process.spawnSync('timeout', ['/T', '10'])
Wenn Sie Golf "codieren" möchten, können Sie hier eine kürzere Version einiger anderer Antworten erstellen:
Aber meiner Meinung nach ist die ideale Antwort die Verwendung der Node-
util
Bibliothek und ihrerpromisify
Funktion, die genau für diese Art von Dingen entwickelt wurde (Versprechensbasierte Versionen von zuvor existierenden, nicht auf Versprechungen basierenden Dingen):In beiden Fällen können Sie dann einfach anhalten, indem Sie
await
Ihresleep
Funktion aufrufen :quelle
await
. Es erstellt sozusagen einen Rückruf, hält die Dinge an und startet den Code neu, wenn dieser Rückruf zurückkehrt. Der Rückruf wird mit einem Wert zurückgegeben, aber in diesem Fall ist uns das egal, sodass links nichts stehtawait
.Ich habe kürzlich eine einfachere Abstraktion namens wait.for erstellt , um asynchrone Funktionen im Synchronisationsmodus (basierend auf Knotenfasern) aufzurufen. Es gibt auch eine Version, die auf kommenden ES6-Generatoren basiert.
https://github.com/luciotato/waitfor
Mit wait.for können Sie jede asynchrone Standardfunktion von nodejs aufrufen, als wäre es eine Synchronisierungsfunktion, ohne die Ereignisschleife des Knotens zu blockieren.
Sie können bei Bedarf nacheinander codieren, was (ich vermute) perfekt ist, um Ihre Skripte für den persönlichen Gebrauch zu vereinfachen.
Verwenden Sie wait.for Ihr Code lautet :
Auch jede Async-Funktion kann im Sync- Modus aufgerufen werden. Überprüfen Sie die Beispiele.
quelle
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
stieß ich auf einen anderen Fehler im Zusammenhang mit undefinierten Eigenschaften usw. Also musste ich sie auch kopieren. Warum organisieren Sie den Code nicht so, dass dies nicht erforderlich ist?Da die Javascript-Engine (v8) Code basierend auf der Abfolge von Ereignissen in der Ereigniswarteschlange ausführt, gibt es keine Vorgabe, dass Javascript die Ausführung genau nach dem angegebenen Zeitpunkt auslöst. Wenn Sie also einige Sekunden festlegen, um den Code später auszuführen, basiert das Auslösen des Codes ausschließlich auf der Reihenfolge in der Ereigniswarteschlange. Das Auslösen der Codeausführung kann daher länger als angegeben dauern.
Also folgt Node.js,
um den Code später auszuführen, setzen Sie stattdessen setTimeout (). Zum Beispiel,
quelle
Mit ES6-Unterstützung
Promise
können wir sie ohne fremde Hilfe verwenden.Dann benutze es so:
Beachten Sie, dass die
doWhat
Funktion zumresolve
Rückruf innerhalb der wirdnew Promise(...)
.Beachten Sie auch, dass dies ASYNCHRONER Schlaf ist. Die Ereignisschleife wird nicht blockiert. Wenn Sie den Schlaf blockieren müssen, verwenden Sie diese Bibliothek, die mithilfe von C ++ - Bindungen den Block blockiert. (Obwohl die Notwendigkeit eines blockierenden Schlafes in Node-ähnlichen asynchronen Umgebungen selten ist.)
https://github.com/erikdubbelboer/node-sleep
quelle
Dieser Code oben ist der Nebeneffekt der Lösung des Problems der asynchronen Rückruf-Hölle von Javascript. Dies ist auch der Grund, warum ich denke, dass Javascript eine nützliche Sprache im Backend ist. Tatsächlich ist dies meiner Meinung nach die aufregendste Verbesserung des modernen Javascript. Um vollständig zu verstehen, wie es funktioniert, muss die Funktionsweise des Generators vollständig verstanden werden. Das
function
Schlüsselwort gefolgt von a*
wird im modernen Javascript als Generatorfunktion bezeichnet. Das npm-Paketco
bot eine Runner-Funktion zum Betreiben eines Generators.Im Wesentlichen bot die Generatorfunktion eine Möglichkeit, die Ausführung einer Funktion mit einem
yield
Schlüsselwort zu unterbrechen, während gleichzeitigyield
eine Generatorfunktion den Informationsaustausch zwischen dem Generator und dem Aufrufer ermöglichte. Dies stellte einenpromise
Aufruf für den Aufrufer bereit, Daten aus einem asynchronen Aufruf zu extrahieren und die aufgelösten Daten an den Generator zurückzugeben. Tatsächlich wird ein asynchroner Anruf synchronisiert.quelle
Dies ist ein Modul mit moment.js-Geschmack, das auf dem von @ atlex2 vorgeschlagenen Dirty-Blocking-Ansatz basiert . Verwenden Sie dies nur zum Testen .
quelle
Wenn Sie die aktuelle Thread-Ausführung nur zu Testzwecken anhalten müssen, versuchen Sie Folgendes:
quelle
Einfach gesagt, wir werden 5 Sekunden warten, bis ein Ereignis eintritt (dies wird durch die Variable done angezeigt, die an einer anderen Stelle im Code auf true gesetzt ist) oder wenn das Timeout abläuft, werden wir alle 100 ms überprüfen
quelle
Bei einigen Personen funktioniert die akzeptierte Antwort nicht. Ich habe diese andere Antwort gefunden und sie funktioniert bei mir: Wie kann ich einen Parameter an einen setTimeout () - Rückruf übergeben?
'Hallo' ist der Parameter, der übergeben wird. Sie können alle Parameter nach Ablauf der Zeitüberschreitung übergeben. Vielen Dank an @Fabio Phms für die Antwort.
quelle
Anstatt all diese setTimeout-, Schlaf- und viele andere Dinge zu tun, ist es besser, sie zu verwenden
quelle
Die anderen Antworten sind großartig, aber ich dachte, ich würde einen anderen Takt wählen.
Wenn alles, was Sie wirklich suchen, darin besteht, eine bestimmte Datei unter Linux zu verlangsamen:
Knoten myprog slowfile
Dies wird alle fünf Zeilen 1 Sekunde lang schlafen. Das Knotenprogramm wird so langsam wie der Writer. Wenn es andere Dinge tut, werden sie mit normaler Geschwindigkeit fortgesetzt.
Das mkfifo erstellt eine First-In-First-Out-Pipe. Das macht diese Arbeit aus. Die Perl-Zeile schreibt so schnell, wie Sie möchten. Das $ | = 1 sagt, dass die Ausgabe nicht gepuffert werden soll.
quelle
Nachdem ich die Antworten in dieser Frage gelesen habe, habe ich eine einfache Funktion zusammengestellt, die bei Bedarf auch einen Rückruf durchführen kann:
quelle
Für weitere Informationen über
Sie sollten Redux-Saga überprüfen . Es ist jedoch spezifisch für Ihre Wahl von Redux als Modell-Framework (obwohl dies unbedingt nicht erforderlich ist).
quelle