nodejs node generators generadora funcion await async javascript node.js yield

node - yield javascript



Cómo puedo esperar en Node.js(Javascript), necesito hacer una pausa por un período de tiempo (23)

Estoy desarrollando una consola como script para necesidades personales ... Necesito poder hacer una pausa por un período prolongado de tiempo, pero como node.js de mi investigación no tiene forma de detenerse como se requiere ... Se está poniendo difícil para leer la información de los usuarios después de un período de tiempo ... vi un código por ahí, pero creo que tienen que tener otros códigos para que funcionen, como:

setTimeout(function() { }, 3000);

Pero este problema es que necesito todo después de esta línea de código para ejecutarse después del período de tiempo ...

Por ejemplo,

//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.

También he visto cosas como

yield sleep(2000);

Pero node.js no reconoce esto ....

Si alguien está dispuesto a ayudar, es muy apreciado.


Función de sueño simple y elegante con Javascript moderno

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

Sin dependencias, sin infierno de devolución de llamadas; Eso es :-)

Teniendo en cuenta el ejemplo dado en la pregunta, así es como dormiríamos entre dos registros de consola:

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

El "inconveniente" es que su función principal ahora también tiene que ser async . Pero, considerando que ya está escribiendo código Javascript moderno, es probable que esté (o al menos debería estarlo) usando async / await todo su código, por lo que realmente no es un problema. Todos los navegadores modernos de hoy lo support .

Dando un poco de información sobre la función de sleep para aquellos que no están acostumbrados a los operadores async/await y flecha gruesa, esta es la forma detallada de escribirlo:

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

Sin embargo, el uso del operador de flecha gruesa lo hace aún más pequeño (y más elegante).


Coloque el código que desea ejecutar después de la demora dentro de la setTimeout llamada setTimeout :

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


Dado que, el motor javascript (v8) ejecuta el código basado en la secuencia de eventos en la cola de eventos, no hay ningún criterio estricto de que javascript desencadene la ejecución exactamente después del tiempo especificado. Es decir, cuando configura algunos segundos para ejecutar el código más tarde, el código de activación se basa únicamente en la secuencia en la cola de eventos. Por lo tanto, la ejecución de código puede demorar más de lo especificado.

Entonces Node.js sigue,

process.nextTick()

para ejecutar el código más tarde en lugar de setTimeout (). Por ejemplo,

process.nextTick(function(){ console.log("This will be printed later"); });


Eche un vistazo a readline-sync ( https://www.npmjs.com/package/readline-sync )

Instalar con 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); } }

Tal vez no sea la mejor práctica pero hace el trabajo por mí


En Linux / nodejs esto funciona para mí:

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

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

Está bloqueando, pero no es un bucle de espera ocupado.

El tiempo que especifique es en segundos, pero puede ser una fracción. No sé si otros sistemas operativos tienen un comando similar.


Esta es una técnica de bloqueo simple:

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

Se está bloqueando en la medida en que no sucederá nada más en su script (como devoluciones de llamada). Pero como se trata de un script de consola, ¡tal vez sea lo que necesitas!


Esta pregunta es bastante antigua, pero recientemente V8 ha agregado Generadores que pueden lograr lo que el OP solicitó. En general, los generadores son más fáciles de usar para las interacciones asíncronas con la asistencia de una biblioteca, como suspend o gen-run .

Aquí hay un ejemplo usando suspender:

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

Lectura relacionada (a través de una auto promoción descarada): ¿Cuál es el problema con los generadores? .


Este es un módulo de moment.js con sabor basado en el enfoque de bloqueo sucio sugerido por @ atlex2 . Use esto solo para pruebas .

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


La mejor manera de hacer esto es dividir tu código en múltiples funciones, como esta:

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);

Es similar a la solución de JohnnyHK , pero mucho más limpia y fácil de extender.


La solución más corta sin ninguna dependencia:

await new Promise(done => setTimeout(done, 5000));


Las otras respuestas son geniales, pero pensé que tomaría un tacto diferente.

Si lo que realmente está buscando es ralentizar un archivo específico en linux:

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

nodo myprog slowfile

Esto dormirá 1 segundo cada cinco líneas. El programa del nodo irá tan lento como el escritor. Si está haciendo otras cosas, continuarán a velocidad normal.

El mkfifo crea una tubería primero en entrar, primero en salir. Es lo que hace que esto funcione. La línea de Perl escribirá tan rápido como quieras. El $ | = 1 dice que no se almacena en buffer la salida.


Para algunas personas, la respuesta aceptada no funciona, encontré esta otra respuesta y está funcionando para mí: ¿Cómo puedo pasar un parámetro a una devolución de llamada setTimeout ()?

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

''hola'' es el parámetro que se pasa, puede pasar todos los parámetros después del tiempo de espera. Gracias a @Fabio Phms por la respuesta.


Para más información sobre

yield sleep(2000);

Usted debe comprobar Redux-Saga . Pero es específico para su elección de Redux como marco de su modelo (aunque estrictamente no es necesario).



Quería un sueño asíncrono que funcionara en Windows y Linux, sin saturar mi CPU con un bucle largo. Probé el paquete de suspensión pero no se instalaría en mi caja de Windows. Terminé usando:

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

Para instalarlo, escriba:

npm install system-sleep

En tu código,

var sleep = require(''system-sleep''); sleep(10*1000); // sleep for 10 seconds

Funciona de maravilla.


Recientemente he creado una abstracción más simple llamada wait.for para llamar funciones asíncronas en modo de sincronización (basado en fibras de nodo). También hay una versión basada en los próximos generadores ES6.

https://github.com/luciotato/waitfor

Usando wait.for , puede llamar a cualquier función asíncrona de nodejs estándar, como si fuera una función de sincronización, sin bloquear el bucle de eventos del nodo.

Puede codificar secuencialmente cuando lo necesite, lo cual es (supongo) perfecto para simplificar sus scripts para uso personal.

usando wait.for tu código será:

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.

También se puede llamar a cualquier función asíncrona en modo Sync . Revisa los ejemplos.


Reuní, después de haber leído las respuestas en esta pregunta, una función simple que también puede hacer una devolución de llamada, si necesita eso:

function waitFor(ms, cb) { var waitTill = new Date(new Date().getTime() + ms); while(waitTill > new Date()){}; if (cb) { cb() } else { return true } }


Si ES6 es compatible con Promise s, podemos usarlos sin ayuda de terceros.

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.

Entonces úsalo así:

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

Tenga en cuenta que la función doWhat convierte en la devolución de llamada de resolve dentro de la new Promise(...) .

También tenga en cuenta que esto es el sueño ASINCRÓNICO. No bloquea el bucle de eventos. Si necesita bloquear el sueño, use esta biblioteca que realiza el bloqueo del sueño con la ayuda de los enlaces de C ++. (Aunque la necesidad de un bloqueo del sueño en entornos asíncronos como Node es rara).

node-sleep


Si desea "codificar golf", puede hacer una versión más corta de algunas de las otras respuestas aquí:

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

Pero, en realidad, la respuesta ideal en mi opinión es utilizar la biblioteca util de Node y su función promisify , que está diseñada para este tipo de cosas exactamente (hacer versiones basadas en promesas de cosas previamente no basadas en promesas):

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

En cualquier caso, puede hacer una pausa simplemente utilizando await para llamar a su función de sleep :

await sleep(1000); // sleep for 1s/1000ms


Si solo necesita suspender con el fin de probar su ejecución de subprocesos actual, intente esto:

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


Una nueva respuesta a una vieja pregunta. Hoy (enero de 2017) es mucho más fácil. Puede utilizar la nueva sintaxis async/await . Por ejemplo:

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

Para usar async/await out of the box sin instalar y los complementos, debe usar node-v7 o node-v8, usando el indicador --harmony .

Más información:


simple, vamos a esperar 5 segundos para que ocurra algún evento (lo que se indicaría mediante la variable done establecida en true en otra parte del código) o cuando expire el tiempo de espera, lo verificaremos cada 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; } })();


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''); });

Este código anterior es el efecto secundario de resolver el problema del infierno de devolución de llamada asíncrona de Javascript. Esta es también la razón por la que creo que hace de Javascript un lenguaje útil en el backend. En realidad, esta es la mejora más emocionante introducida al Javascript moderno en mi opinión. Para comprender completamente cómo funciona, cómo debe funcionar el generador debe entenderse completamente. La palabra clave de function seguida de un * se denomina función de generador en Javascript moderno. El paquete npm co proporcionó una función de corredor para ejecutar un generador.

Esencialmente, la función del generador proporcionó una forma de pausar la ejecución de una función con la palabra clave de yield , al mismo tiempo, el yield en una función del generador hizo posible el intercambio de información entre el generador y la persona que llama. Esto proporcionó un mecanismo para que la persona que llama extraiga datos de una promise de una llamada asíncrona y devuelva los datos resueltos al generador. Efectivamente, hace una llamada asíncrona sincrónica.