Estoy desarrollando un script de consola para necesidades personales. Necesito poder hacer una pausa durante un período prolongado de tiempo, pero, según mi investigación, Node.js no tiene forma de detenerse según sea necesario. Se está volviendo difícil leer la información de los usuarios después de un período de tiempo ... He visto algo de código, pero creo que tienen que tener otro código dentro de ellos para que funcionen, como:
setTimeout(function() {
}, 3000);
Sin embargo, necesito todo después de esta línea de código para ejecutar 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');
// end of code
También he visto cosas como
yield sleep(2000);
Pero Node.js no reconoce esto.
¿Cómo puedo lograr esta pausa extendida?
javascript
node.js
yield
Christopher Allen
fuente
fuente
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Respuestas:
La mejor manera de hacerlo es dividir su código en múltiples funciones, como esta:
Es similar a la solución de JohnnyHK , pero mucho más ordenada y fácil de extender.
fuente
debugger;
Una nueva respuesta a una vieja pregunta. Hoy (
enero 2017junio 2019) es mucho más fácil. Puede usar la nuevaasync/await
sintaxis . Por ejemplo:Para usarasync/await
de forma inmediata sin instalar y complementos, debe usar node-v7 o node-v8, usando la--harmony
bandera.Actualización de junio de 2019: al usar las últimas versiones de NodeJS, puede usarlo de inmediato. No es necesario proporcionar argumentos de línea de comando. Incluso Google Chrome lo admite hoy.
Actualización de mayo de 2020: pronto podrá utilizar la
await
sintaxis fuera de una función asíncrona. En el nivel superior como en este ejemploLa propuesta está en la etapa 3 . Puede usarlo hoy usando webpack 5 (alfa),
Más información:
fuente
await
palabra clave delante desleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Para fanáticos de línea como yo :)let sleep = require('util').promisify(setTimeout);
funciona en el Nodo 7.6+ y mejora la legibilidadLa solución más corta sin ninguna dependencia:
fuente
let sleep = require('util').promisify(setTimeout);
son tres caracteres más largos pero reutilizables y más legibles en la OMIresolve
lugar dedone
. Es decirawait new Promise(resolve => setTimeout(resolve, 5000))
Ponga el código que desea ejecutar después del retraso dentro de la
setTimeout
devolución de llamada:fuente
node-fibers
. Echale un vistazo.Esta es una técnica de bloqueo simple:
Se está bloqueando en la medida en que nada más sucederá en su script (como devoluciones de llamada). Pero como se trata de un script de consola, ¡tal vez sea lo que necesita!
fuente
wait
, bloquea y funciona para algún propósito de prueba. Exactamente lo que estaba buscando.spin-wait
.En el nodo 7.6.0 o superior
El nodo admite esperar de forma nativa:
entonces si puedes usar funciones asíncronas:
o:
En versiones anteriores de Node (respuesta original)
Quería una suspensión asincrónica que funcionara en Windows y Linux, sin acaparar mi CPU con un ciclo de tiempo largo. Probé el paquete de suspensión pero no se instaló en mi caja de Windows. Terminé usando:
https://www.npmjs.com/package/system-sleep
Para instalarlo, escriba:
En su código
Funciona de maravilla.
fuente
Función de sueño simple y elegante usando Javascript moderno
Sin dependencias, sin devolución de llamada infierno; Eso es :-)
Considerando el ejemplo dado en la pregunta, así es como dormiríamos entre dos registros de consola:
El "inconveniente" es que su función principal ahora también debe serlo
async
. Pero, teniendo en cuenta que ya está escribiendo un código Javascript moderno, probablemente esté (¡o al menos debería hacerlo!) Utilizandoasync
/await
todo su código, por lo que esto realmente no es un problema. Todos los navegadores modernos de hoy lo admiten .Dando una pequeña idea de la
sleep
función para aquellos que no están acostumbradosasync/await
y operadores de flecha gruesa, esta es la forma detallada de escribirlo:Sin embargo, el uso del operador de flecha gruesa lo hace aún más pequeño (y más elegante).
fuente
async
y dejando todo lo demás igual. Probablemente es más claro con elasync
sin embargo.async
. Edité mi respuesta con su sugerencia. No creo que aclare el código; para eso, recurriría a JSDoc en su lugar.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Puede usar este www.npmjs.com/package/sleep
fuente
MacOS
, pero encuentra erroresCentOS
debido a errores de node_gyp . Parece que no es portátil.Esta pregunta es bastante antigua, pero recientemente V8 ha agregado generadores que pueden lograr lo que solicitó el OP. Los generadores son generalmente más fáciles de usar para las interacciones asíncronas con la ayuda de una biblioteca como suspender o gen-run .
Aquí hay un ejemplo usando suspender:
Lectura relacionada (a modo de autopromoción descarada): ¿Cuál es el gran problema con los generadores? .
fuente
yield setTimeout(suspend.resume(), 10000);
--harmony
bandera, y de acuerdo con node.green, al menos están disponibles sin ninguna bandera desde v4.8.4: node.green/#ES2015-functions-generators-basic-functionality . Sin embargo, tenga en cuenta que la nuevaasync/await
sintaxis proporciona una mejor solución a esto ahora, sin necesidad de bibliotecas adicionales comosuspend
. Consulte esta respuesta para ver un ejemplo: stackoverflow.com/a/41957152/376789 . Las funciones asíncronas están disponibles (sin banderas) desde la v7.10.En Linux / nodejs esto funciona para mí:
Está bloqueando, pero no es un ciclo 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.
fuente
sleep
es bastante omnipresente y útil desde los primeros días de UNIX en.wikipedia.org/wiki/Sleep_%28Unix%29 . Sólo "no es raro" OS que tal vez no existiría es Windows (sin embargo no se podría intentarchild_process.spawnSync('timeout', ['/T', '10'])
Si desea "codificar golf", puede hacer una versión más corta de algunas de las otras respuestas aquí:
Pero realmente la respuesta ideal en mi opinión es usar la
util
biblioteca de Node y supromisify
función, que está diseñada exactamente para este tipo de cosas (hacer versiones basadas en promesas de cosas previamente no basadas en promesas):En cualquier caso, puede pausar simplemente usando
await
para llamar a susleep
función:fuente
await
. Crea una devolución de llamada, pausa las cosas y luego reinicia el código cuando vuelve la devolución de llamada. La devolución de llamada regresa con un valor, pero no nos importa en este caso, por lo que no hay nada a la izquierdaawait
.Recientemente he creado una abstracción más simple llamada wait.for para llamar a 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, que es, (supongo) perfecto para simplificar sus scripts para uso personal.
usando wait.for su código será:
También se puede llamar a cualquier función asíncrona en modo Sincronización . Mira los ejemplos.
fuente
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
encontré otros errores relacionados con propiedades indefinidas, etc. Así que también tuve que copiarlos. ¿Por qué no organizas el código de manera que no sea necesario?Dado que el motor de JavaScript (v8) ejecuta código basado en la secuencia de eventos en la cola de eventos, no es estricto que JavaScript active exactamente la ejecución después de un tiempo especificado. Es decir, cuando configura unos segundos para ejecutar el código más tarde, el código de activación se basa puramente en la secuencia en la cola de eventos. Por lo tanto, activar la ejecución de código puede llevar más tiempo que el especificado.
Entonces Node.js sigue,
para ejecutar el código más tarde en su lugar setTimeout (). Por ejemplo,
fuente
Con ES6 compatible con
Promise
s, podemos usarlos sin ayuda de terceros.Entonces úsalo así:
Tenga en cuenta que la
doWhat
función se convierte en laresolve
devolución de llamada dentro delnew Promise(...)
.También tenga en cuenta que este 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 enlaces C ++. (Aunque la necesidad de un bloqueo de suspensión en Nodo como entornos asíncronos es rara).
https://github.com/erikdubbelboer/node-sleep
fuente
Este código anterior es el efecto secundario de resolver el problema del infierno de devolución de llamada asincrónica de Javascript. Esta es también la razón por la que creo que hace que Javascript sea 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, es necesario comprender completamente cómo funciona el generador. La
function
palabra clave seguida de a*
se llama función generadora en Javascript moderno. El paquete npmco
proporcionó una función de corredor para ejecutar un generador.Esencialmente, la función de generador proporcionó una forma de pausar la ejecución de una función con una
yield
palabra clave, al mismo tiempo,yield
en una función de generador hizo posible intercambiar información entre el generador y la persona que llama. Esto proporcionó un mecanismo para que la persona que llama extraiga los datos de unapromise
llamada asincrónica y devuelva los datos resueltos al generador. Efectivamente, realiza una llamada asincrónica sincrónica.fuente
Este es un módulo con sabor moment.js basado en el enfoque de bloqueo sucio sugerido por @ atlex2 . Use esto solo para pruebas .
fuente
Si solo necesita suspender para probar su ejecución actual de subprocesos, intente esto:
fuente
simple, vamos a esperar 5 segundos para que suceda algún evento (eso se indicaría mediante la variable hecha establecida en verdadero en otro lugar del código) o cuando caduque el tiempo de espera que verificaremos cada 100 ms
fuente
Para algunas personas, la respuesta aceptada no funciona, encontré esta otra respuesta y funciona para mí: ¿Cómo puedo pasar un parámetro a una devolución de llamada setTimeout ()?
'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.
fuente
En lugar de hacer todos estos setTimeout, dormir y muchas otras cosas, es mejor usar
fuente
Las otras respuestas son geniales, pero pensé que tomaría un tacto diferente.
Si todo lo que realmente está buscando es reducir la velocidad de un archivo específico en Linux:
nodo myprog archivo lento
Esto dormirá 1 segundo cada cinco líneas. El programa de nodo irá tan lento como el escritor. Si está haciendo otras cosas, continuarán a la velocidad normal.
El mkfifo crea una tubería primero en entrar, primero en salir. Es lo que hace que esto funcione. La línea perl escribirá tan rápido como quieras. El $ | = 1 dice no amortiguar la salida.
fuente
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 lo necesita:
fuente
Para más información sobre
deberías revisar Redux-Saga . Pero es específico para su elección de Redux como su marco modelo (aunque estrictamente no es necesario).
fuente