Ik ontwikkel een consolescript voor persoonlijke behoeften. Ik moet een langere tijd kunnen pauzeren, maar uit mijn onderzoek kan Node.js niet stoppen zoals vereist. Het wordt na verloop van tijd moeilijk om de informatie van gebruikers te lezen… Ik heb wat code gezien, maar ik geloof dat ze andere code in zich moeten hebben om te kunnen werken, zoals:
setTimeout(function() {
}, 3000);
Ik heb echter alles na deze regel code nodig om na verloop van tijd uit te voeren.
Bijvoorbeeld
// start of code
console.log('Welcome to my console,');
some-wait-code-here-for-ten-seconds...
console.log('Blah blah blah blah extra-blah');
// end of code
Ik heb ook dingen gezien als
yield sleep(2000);
Maar Node.js herkent dit niet.
Hoe kan ik deze verlengde pauze bereiken?
Antwoord 1, autoriteit 100%
Update januari 2021: je kunt het zelfs doen in de Node REPL interactive met --experimental-repl-await
flag
$ node --experimental-repl-await
> const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
> await delay(1000) /// waiting 1 second.
Een nieuw antwoord op een oude vraag. Vandaag ( jan 2017juni 2019) is het veel makkelijker. U kunt de nieuwe async/await
syntaxis.
Bijvoorbeeld:
async function init() {
console.log(1);
await sleep(1000);
console.log(2);
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
Voor het gebruik van async/await
uit de doos zonder installatie en plug-ins, moet je node-v7 of node-v8 gebruiken, met behulp van de --harmony
vlag.
Update juni 2019:door de nieuwste versies van NodeJS te gebruiken, kunt u deze direct gebruiken. U hoeft geen opdrachtregelargumenten op te geven. Zelfs Google Chrome ondersteunt het tegenwoordig.
Update mei 2020:
Binnenkort kunt u de syntaxis await
gebruiken buiten een async-functie. Op het hoogste niveau zoals in dit voorbeeld
await sleep(1000)
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
Het voorstel bevindt zich in fase 3.
Je kunt het vandaag nog gebruiken door webpack 5 (alpha) te gebruiken,
Meer info:
- Harmony-vlag in Nodejs: https://nodejs.org/en/docs/es6/
- Alle NodeJS-versies om te downloaden: https://nodejs.org/en/download/releases/
Antwoord 2, autoriteit 66%
De kortste oplossing zonder enige afhankelijkheden:
await new Promise(resolve => setTimeout(resolve, 5000));
Antwoord 3, autoriteit 38%
De beste manier om dit te doen, is door uw code op te splitsen in meerdere functies, zoals deze:
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);
Het lijkt op de oplossing van JohnnyHK, maar is veel netter en gemakkelijker uit te breiden.
Antwoord 4, autoriteit 26%
Dit is een eenvoudige blokkeringstechniek:
var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}
Het blokkeertvoor zover er niets anders in je script gebeurt (zoals callbacks). Maar aangezien dit een consolescript is, is het misschien wat je nodig hebt!
Antwoord 5, autoriteit 24%
Plaats de code die u wilt uitvoeren na de vertraging binnen de setTimeout
callback:
console.log('Welcome to My Console,');
setTimeout(function() {
console.log('Blah blah blah blah extra-blah');
}, 3000);
Antwoord 6, autoriteit 13%
Op Node 7.6.0 of hoger
Node ondersteunt native wachten:
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
Dan als u ASYNC-functies kunt gebruiken:
await sleep(10000); // sleep for 10 seconds
of:
sleep(10000).then(() => {
// This will execute 10 seconds from now
});
op oudere knooppunten (origineel antwoord)
Ik wilde een asynchrone slaap die werkte in Windows & AMP; Linux, zonder mijn CPU te zwaaien met een lange tijd. Ik heb het slaappakket geprobeerd, maar het zou niet installeren op mijn Windows-doos. Ik eindigde met het gebruik van:
https://www.npmjs.com/package/system-sleep < / p>
Typ:
npm install system-sleep
in uw code,
var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds
werkt als een charme.
Antwoord 7, Autoriteit 10%
Eenvoudige en elegante slaapfunctie met behulp van moderne Javascript
function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
Geen afhankelijkheden, geen callback-hel; Dat is het: -)
Gezien het voorbeeld in de vraag, is dit hoe we zouden slapen tussen twee console-logs:
async function main() {
console.log("Foo");
await sleep(2000);
console.log("Bar");
}
main();
Het “nadeel” is dat je hoofdfunctie nu ook async
moet zijn. Maar aangezien je al moderne Javascript-code schrijft, gebruik je waarschijnlijk (of zou je dat in ieder geval moeten doen!) async
/await
in je hele code, dus dit is echt niet een probleem. Alle moderne browsers ondersteunenhet.
Om een beetje inzicht te geven in de sleep
-functie voor degenen die niet gewend zijn aan async/await
en fat arrow-operators, dit is de uitgebreide manier om het te schrijven:
function sleep(millis) {
return new Promise(function (resolve, reject) {
setTimeout(function () { resolve(); }, millis);
});
}
Het gebruik van de fat arrow-operator maakt het echter nog kleiner (en eleganter).
Antwoord 8, autoriteit 8%
U kunt deze www.npmjs.com/package/sleep
gebruiken
var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds
Antwoord 9, autoriteit 5%
Deze vraag is vrij oud, maar onlangs heeft V8 generatoren toegevoegd die kunnen bereiken wat de OP heeft gevraagd. Generatoren zijn over het algemeen het gemakkelijkst te gebruiken voor asynchrone interacties met behulp van een bibliotheek zoals suspendof gen-run.
Hier is een voorbeeld van het gebruik van opschorten:
suspend(function* () {
console.log('Welcome to My Console,');
yield setTimeout(suspend.resume(), 10000); // 10 seconds pass..
console.log('Blah blah blah blah extra-blah');
})();
Gerelateerde literatuur (bij wijze van schaamteloze zelfpromotie): Wat is het probleem met generatoren?.
Antwoord 10, autoriteit 5%
Als u golf wilt “coderen”, kunt u hier een kortere versie van enkele van de andere antwoorden maken:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Maar naar mijn mening is het ideale antwoord om de util
-bibliotheek van Node en de functie promisify
te gebruiken, die voor precies dit soort dingen is ontworpen (op beloften gebaseerd versies van eerder bestaande niet-belofte-gebaseerde dingen):
const util = require('util');
const sleep = util.promisify(setTimeout);
In beide gevallen kunt u eenvoudig pauzeren door await
te gebruiken om uw sleep
-functie aan te roepen:
await sleep(1000); // sleep for 1s/1000ms
BEWERKEN:Zoals opgemerkt in de opmerkingen, kun je dat zelfs terugbrengen tot één regel:
const sleep = require('util').promisify(setTimeout);
Of, als je niet eens de moeite wilt nemen om een sleep
-functie te maken:
await require('util').promisify(setTimeout)(1000);
Antwoord 11, autoriteit 3%
Op Linux/nodejs werkt dit voor mij:
const spawnSync = required(‘child_process’).spawnSync;
var sleep = spawnSync(‘sleep’, [1.5]);
Het blokkeert, maar het is geen drukke wachtlus.
De tijd die je opgeeft is in seconden, maar kan ook een breuk zijn. Ik weet niet of andere besturingssystemen een soortgelijk commando hebben.
Antwoord 12, autoriteit 2%
Ik heb onlangs een eenvoudigere abstractie gemaakt met de naam wait.forom asynchrone functies aan te roepen in de synchronisatiemodus (gebaseerd op knooppuntvezels). Er is ook een versie die is gebaseerd op aankomende ES6-generatoren.
https://github.com/luciotato/waitfor
Met wait.forkun je elke standaard nodejs async-functie aanroepen, alsof het een sync-functie is, zonder de event-lus van de node te blokkeren.
Je kunt opeenvolgend coderen wanneer je het nodig hebt, wat (denk ik) perfect is om je scripts te vereenvoudigen voor persoonlijk gebruik.
met behulp van wait.forwordt uw code:
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.
Ook elke asynchrone functie kan worden aangeroepen in de modus Sync.
Bekijk de voorbeelden.
Antwoord 13
Aangezien javascript-engine (v8) code uitvoert op basis van de volgorde van gebeurtenissen in de gebeurteniswachtrij, is er geen strikte eis dat javascript de uitvoering precies op een bepaald tijdstip activeert. Dat wil zeggen, wanneer u enkele seconden instelt om de code later uit te voeren, is het activeren van code puur gebaseerd op de volgorde in de gebeurteniswachtrij. Dus het activeren van de uitvoering van code kan meer tijd in beslag nemen dan de opgegeven tijd.
Dus Node.js volgt,
process.nextTick()
Om de code later uit te voeren in plaats daarvan in SetTimeout (). Bijvoorbeeld,
process.nextTick(function(){
console.log("This will be printed later");
});
Antwoord 14
Met ES6-ondersteuning Promise
S, kunnen we ze gebruiken zonder hulp van derden.
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.
Gebruik het dan als volgt:
const waitThenDo(howLong, doWhat) => {
return sleep(howLong).then(doWhat);
};
Merk op dat de doWhat
-functie wordt de resolve
callback in de new Promise(...)
.
.
Merk ook op dat dit asynchrone slaap is. Het blokkeert de gebeurtenislus niet. Als u de slaap nodig hebt, gebruikt u deze bibliotheek die zich realiseert met blokkering met de hulp van C++ -bindingen. (Hoewel de behoefte aan een blokkerende slaap in knooppuntachtige async-omgevingen zeldzaam is.)
https://github.com/erikdubbelboer/nod-sleep
Antwoord 15
Probeer de belofte te gebruiken, het werkt voor mij in NODEJS
één voering
await new Promise(resolve => setTimeout(resolve, 5000));
of laat het als een functie in NodeJS
om opnieuw te gebruiken
const sleep = async (milliseconds) => {
await new Promise(resolve => setTimeout(resolve, milliseconds));
}
gebruik de functie zoals
await sleep(5000)
Antwoord 16
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');
});
Deze code hierboven is het neveneffect van het oplossen van het asynchrone callback hell-probleem van Javascript. Dit is ook de reden waarom ik denk dat Javascript een nuttige taal in de backend is. Eigenlijk is dit naar mijn mening de meest opwindende verbetering die in het moderne Javascript is geïntroduceerd. Om volledig te begrijpen hoe het werkt, moet de generator volledig worden begrepen. Het sleutelwoord function
gevolgd door een *
wordt in modern Javascript een generatorfunctie genoemd. Het npm-pakket co
bood een runner-functie om een generator te laten draaien.
In wezen een generatorfunctie bood een manier om de uitvoering van een functie met het trefwoord yield
te pauzeren, terwijl tegelijkertijd yield
in een generatorfunctie het mogelijk maakte om informatie uit te wisselen tussen de binnenkant van de generator en de beller. Dit leverde een mechanisme voor de beller om gegevens te extraheren uit een promise
van een asynchrone oproep en om de opgeloste gegevens terug te sturen naar de generator. In feite maakt het een asynchrone oproep synchroon.
Antwoord 17
Dit is een module met de smaak van moment.js, gebaseerd op de vuile blokkeringsaanpak die wordt voorgesteld door @atlex2. Gebruik dit alleen om te testen.
const moment = require('moment');
let sleep = (secondsToSleep = 1) => {
let sleepUntill = moment().add(secondsToSleep, 'seconds');
while(moment().isBefore(sleepUntill)) { /* block the process */ }
}
module.exports = sleep;
Antwoord 18
eenvoudig, we wachten 5 seconden totdat er een gebeurtenis plaatsvindt (dat wordt aangegeven door de variabele done die ergens anders in de code op true is ingesteld) of wanneer de time-out verloopt, controleren we deze elke 100 ms
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;
}
})();
Antwoord 19
Voor sommige mensen werkt het geaccepteerde antwoord niet, ik heb dit andere antwoord gevonden en het werkt voor mij: Hoe kan ik een parameter doorgeven aan een setTimeout() callback?
var hello = "Hello World";
setTimeout(alert, 1000, hello);
‘hallo’ is de parameter die wordt doorgegeven, u kunt alle parameters doorgeven na de time-outtijd. Met dank aan @Fabio Phms voor het antwoord.
Antwoord 20
function doThen(conditional,then,timer) {
var timer = timer || 1;
var interval = setInterval(function(){
if(conditional()) {
clearInterval(interval);
then();
}
}, timer);
}
Voorbeeld van gebruik:
var counter = 1;
doThen(
function() {
counter++;
return counter == 1000;
},
function() {
console.log("Counter hit 1000"); // 1000 repeats later
}
)
Antwoord 21
Als je de uitvoering van je huidige thread alleen maar wilt onderbreken voor testdoeleinden, probeer dan dit:
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
Antwoord 22
De andere antwoorden zijn geweldig, maar ik dacht dat ik het anders zou aanpakken.
Als alles wat je echt zoekt is om een specifiek bestand in Linux te vertragen:
rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile &
node myprog slowfile
Hierdoor slaapt u elke vijf regels 1 seconde. Het knooppuntprogramma zal net zo langzaam gaan als de schrijver. Als het andere dingen doet, gaan ze op normale snelheid verder.
De mkfifo creëert een first-in-first-out pijp. Het is wat dit werk maakt.
De perl-regel schrijft zo snel als je wilt. De $|=1 zegt dat de uitvoer niet moet worden gebufferd.
Antwoord 23
Ik heb, na het lezen van de antwoorden op deze vraag, een eenvoudige functie samengesteld die ook kan terugbellen, als je dat nodig hebt:
function waitFor(ms, cb) {
var waitTill = new Date(new Date().getTime() + ms);
while(waitTill > new Date()){};
if (cb) {
cb()
} else {
return true
}
}
Antwoord 24
Voor meer informatie over
yield sleep(2000);
je moet Redux-Sagacontroleren. Maar het is specifiek voor uw keuze voor Redux als uw modelraamwerk (hoewel strikt niet noodzakelijk).