¿Hay una mejor manera de diseñar un sleep
JavaScript en la siguiente pausecomp
función ( tomada de aquí )?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
Esto no es un duplicado de Sleep en JavaScript: retraso entre acciones ; Quiero un sueño real en medio de una función, y no un retraso antes de que se ejecute un fragmento de código.
javascript
sleep
fmsf
fuente
fuente
Respuestas:
Actualización 2017-2019
Desde 2009, cuando se hizo esta pregunta, JavaScript ha evolucionado significativamente. Todas las demás respuestas ahora son obsoletas o demasiado complicadas. Aquí está la mejor práctica actual:
Eso es todo.
await sleep(<duration>)
.O como una frase:
Tenga en cuenta que,
await
solo se puede ejecutar en funciones con laasync
palabra clave como prefijo , o en el nivel superior de su script en algunos entornos (por ejemplo, la consola Chrome DevTools o Runkit).await
solo pausa laasync
función actualDos nuevas características de JavaScript ayudaron a escribir esta función de "suspensión":
async/await
característica permite que el código espere explícitamente una promesa de liquidación (resolución o rechazo).Compatibilidad
async
/await
aterrizó en V8 y se ha habilitado de forma predeterminada desde Chrome 55 (lanzado en diciembre de 2016)Si, por alguna extraña razón, está utilizando Nodo anterior a 7 (que ha llegado al final de su vida útil ), o está apuntando a navegadores antiguos,
async
/await
todavía puede usarse a través de Babel (una herramienta que transpilará JavaScript + nuevas funciones en JavaScript antiguo simple) , con eltransform-async-to-generator
complemento.fuente
(Ver la respuesta actualizada para 2016 )
Creo que es perfectamente razonable querer realizar una acción, esperar y luego realizar otra acción. Si estás acostumbrado a escribir en lenguajes multiproceso, probablemente tengas la idea de ejecutar durante un período de tiempo determinado hasta que tu hilo se active.
El problema aquí es que JavaScript es un modelo basado en eventos de un solo hilo. Si bien en un caso específico, puede ser bueno que todo el motor espere unos segundos, en general es una mala práctica. ¿Y si quisiera utilizar sus funciones mientras escribía las mías? Cuando llamé a su método, todos mis métodos se congelaron. Si JavaScript pudiera de alguna manera preservar el contexto de ejecución de su función, guárdelo en algún lugar, luego tráigalo de nuevo y continúe más tarde, luego podría pasar el sueño, pero eso sería básicamente un subproceso.
Por lo tanto, está bastante atascado con lo que otros han sugerido: necesitará dividir su código en múltiples funciones.
Su pregunta es un poco falsa, entonces. No hay forma de dormir de la manera que desea, ni debe buscar la solución que sugiere.
fuente
sleep()
no es posible en JS, y que la mayoría de las veces hay mejores formas de hacer las cosas. Pero aún consideraría la forma en que el motor une todas las cosas como un defecto de diseño; no hay razón para que el lenguaje no pueda tener unasleep()
función limitada a un script, página o función específicos sin que el motor bloquee la CPU y congele la aplicación como un loco. Es 2015 y no deberías poder bloquear un navegador web completowhile(1)
. Tenemos Flash para cosas así.En JavaScript, reescribo cada función para que pueda finalizar lo antes posible. Desea que el navegador vuelva a estar en control para que pueda realizar cambios en su DOM.
Cada vez que quería dormir en el medio de mi función, refactorizaba el uso de a
setTimeout()
.Editar
El sueño infame, o la función de retraso, en cualquier idioma es muy debatido. Algunos dirán que siempre debe haber una señal o devolución de llamada para activar una funcionalidad determinada, otros argumentarán que a veces es útil un momento arbitrario de retraso. Digo que cada uno de ellos tiene una regla y nunca puede dictar nada en esta industria.
Escribir una función de suspensión es simple y se hace aún más utilizable con JavaScript Promises:
fuente
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
Solo para depuración / desarrollo , publico esto si es útil para alguien
Cosas interesantes, en Firebug (y probablemente otras consolas js), no sucede nada después de presionar enter, solo después de la duración del sueño especificada (...)
Ejemplo de uso:
fuente
only for debug/dev
... rolleyesEstoy de acuerdo con los otros carteles, un sueño ocupado es solo una mala idea.
Sin embargo, setTimeout no detiene la ejecución, ejecuta la siguiente línea de la función inmediatamente después de que se establece el tiempo de espera, no después de que expire el tiempo de espera, por lo que no cumple la misma tarea que realizaría un sueño.
La forma de hacerlo es descomponer su función en partes antes y después.
Asegúrese de que los nombres de sus funciones aún describan con precisión lo que hace cada pieza (IE GatherInputThenWait y CheckInput, en lugar de funcPart1 y funcPart2)
Editar
Este método logra el propósito de no ejecutar las líneas de código que usted decida hasta DESPUÉS de su tiempo de espera, al tiempo que devuelve el control a la PC cliente para ejecutar cualquier otra cosa que haya puesto en cola.
Editar más
Como se señaló en los comentarios, esto NO FUNCIONARÁ en un bucle. Podrías hacer un pirateo sofisticado (feo) para que funcione en un bucle, pero en general eso solo generará un código de espagueti desastroso.
fuente
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
yfor(var X = 0; X < 3;X++) { foo(X); }
- se pasa el valor de Xfoo
, que luego se reutiliza bajo el nombreindex
cuandofoo_continue
finalmente se llama.console.log()
interiorfoo_continue()
en la versión setTimeout y obtendrá el mismo resultado.Por amor a $ DEITY, no realice una función de espera de ocupado.
setTimeout
ysetInterval
haz todo lo que necesites.Cada intervalo de dos segundos oculta el texto por un segundo. Esto muestra cómo usar setInterval y setTimeout para mostrar y ocultar texto cada segundo.
fuente
Sé que esta es una pregunta un poco antigua, pero si (como yo) estás usando Javascript con Rhino, puedes usar ...
fuente
Si está utilizando jQuery, alguien realmente creó un complemento de "retraso" que no es más que un contenedor para setTimeout:
Luego puede usarlo en una fila de llamadas a funciones como se esperaba:
fuente
.delay()
es parte de jQuery (aunque con una semántica diferente de la implementación anterior). api.jquery.com/delayTambién busqué la solución de suspensión (no para el código de producción, solo para desarrolladores / pruebas) y encontré este artículo:
http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html
... y aquí hay otro enlace con soluciones del lado del cliente: http://www.devcheater.com/
Además, cuando llame
alert()
, su código también se pausará, mientras se muestra la alerta: debe encontrar una manera de no mostrar la alerta pero obtener el mismo efecto. :)fuente
Aquí hay una solución simple usando un XMLHttpRequest síncrono:
contenido de sleep.php:
Ahora llámalo con: sleep (5);
fuente
setTimeout()
si eso funciona, pero si hacerlo significa desentrañar 1000 líneas de devoluciones de llamada, esto podría comenzar a no parecer una broma.sleep(300)
sitio web y tarda 150 ms en responder, el código de JavaScript se suspenderá durante 450 ms. y si el navegador pierde la conexión a Internet, solo funcionará durante 0 ms. Entonces no es una mejor soluciónAqui tienes. Como dice el código, no seas un mal desarrollador y utilízalo en sitios web. Es una función de utilidad de desarrollo.
fuente
async/await
desafortunadamente en algunos lugares no responde, y tenemos que usarla obligatoriamente.Personalmente me gusta lo simple:
entonces:
Lo estoy usando todo el tiempo para crear tiempo de carga falso mientras creo scripts en P5js
fuente
Primero:
Defina una función que desee ejecutar de esta manera:
Luego programe su ejecución con el método setTimeout:
Nota dos cosas
fuente
asegúrese de que su función de llamada sea asíncrona
verificado y funcionando bien
fuente
Una mejor solución para hacer que las cosas se vean como lo que la mayoría de la gente quiere es usar una función anónima:
Esto es probablemente lo más cerca que estarás de algo que simplemente hace lo que quieres.
Tenga en cuenta que si necesita dormir varias veces, esto puede ponerse feo rápidamente y es posible que deba repensar su diseño.
fuente
Para los navegadores, estoy de acuerdo en que setTimeout y setInterval son el camino a seguir.
Pero para el código del lado del servidor, puede requerir una función de bloqueo (por ejemplo, para que pueda tener una sincronización de subprocesos efectiva).
Si está utilizando node.js y meteor, es posible que se haya encontrado con las limitaciones de usar setTimeout en una fibra. Aquí está el código para la suspensión del lado del servidor.
Ver: https://github.com/laverdet/node-fibers#sleep
fuente
Server may require a blocking function
... No veo cuán forzado es bloquear buena idea bloquear el único hilo de Node y hacer que todo su servidor no responda durante varios segundos, pero lo que seaEncapsularía setTimeOut en una promesa para la coherencia del código con otras tareas asincrónicas: demostración en Fiddle
Usado así:
Es fácil recordar la sintaxis si solía usar Promesas.
fuente
Actualización de 2019 usando Atomics.wait
Debería funcionar en el Nodo 9.3 o superior.
Necesitaba un temporizador bastante preciso en Node.js y funciona muy bien para eso. Sin embargo, parece que hay un soporte extremadamente limitado en los navegadores.
Ejecuté algunos puntos de referencia de temporizador de 10 segundos.
Con setTimeout obtengo un error de hasta 7000 microsegundos. (7 ms)
Con Atomics, mi error parece permanecer por debajo de 600 microsegundos. (0.6ms)
Actualización 2020: en resumen
de la cual se
sleep.jsp
ve una página del lado del servidor, por ejemplo ,fuente
La mayoría de las respuestas aquí son erróneas o, como mínimo, desactualizadas. No hay ninguna razón por la que javascript tenga que ser de un solo subproceso, y de hecho no lo es. Hoy en día, todos los navegadores principales admiten a los trabajadores, antes de que este fuera el caso, otros tiempos de ejecución de JavaScript como Rhino y Node.js admitían subprocesos múltiples.
'Javascript tiene un solo subproceso' no es una respuesta válida. Por ejemplo, ejecutar una función de suspensión dentro de un trabajador no bloquearía ninguno de los códigos que se ejecutan en el subproceso ui.
En tiempos de ejecución más nuevos que admiten generadores y rendimiento, se podría aportar una funcionalidad similar a la función de reposo en un entorno de un solo subproceso:
Esta imitación del sueño es diferente de una verdadera función de sueño, ya que no bloquea el hilo. Es simplemente azúcar por encima de la función setTimeout actual de javascript. Este tipo de funcionalidad se ha implementado en Task.js y debería funcionar hoy en Firefox.
fuente
sleep
usando múltiples trabajadores. Si usa Node.js, las funciones del generador ya están implementadas y pueden usarse como se describe. Los navegadores convencionales no han implementado todos los generadores a partir de hoy.He buscado / buscado en Google bastantes páginas web en JavaScript sleep / wait ... y NO hay respuesta si desea que JavaScript "EJECUTE, RETARDE, EJECUTE" ... lo que la mayoría de la gente recibió fue, "EJECUTAR, EJECUTAR (inútil cosas), RUN "o" RUN, RUN + RUN retrasado "....
Así que comí algunas hamburguesas y pensé ::: aquí hay una solución que funciona ... pero tienes que cortar tus códigos de ejecución ... ::: sí, lo sé, esta es una refactorización más fácil de leer ... . todavía...
//......................................... //Ejemplo 1:
// .................................... // ejemplo2:
// ................. ejemplo3:
// .............. ejemplo4:
fuente
fuente
La solución más corta sin ninguna dependencia:
fuente
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
No puedes dormir así en JavaScript o, más bien, no deberías hacerlo. Ejecutar un ciclo de suspensión o tiempo hará que el navegador del usuario se bloquee hasta que finalice el ciclo.
Use un temporizador, como se especifica en el enlace al que hizo referencia.
fuente
Un escenario en el que es posible que desee una función sleep () en lugar de usar setTimeout () es si tiene una función que responde a un clic del usuario que finalmente terminará abriendo una nueva ventana emergente, es decir, y ha iniciado un procesamiento que requiere un período corto completar antes de que se muestre la ventana emergente. Mover la ventana abierta a un cierre significa que el navegador normalmente la bloquea.
fuente
Puedo entender el propósito de una función de suspensión si tiene que lidiar con la ejecución sincrónica. Las funciones setInterval y setTimeout crean un subproceso de ejecución en paralelo que devuelve la secuencia de ejecución al programa principal, lo que no es efectivo si tiene que esperar un resultado dado. Por supuesto, uno puede usar eventos y controladores, pero en algunos casos no es lo que se pretende.
fuente
Agregando mis dos bits. Necesitaba una espera ocupada para fines de prueba. No quería dividir el código, ya que sería mucho trabajo, así que lo hice por mí.
No veo ningún inconveniente en hacer esto y me sirvió.
fuente
for
bucles casi siempre se ejecutará de inmediato, independientemente del valor máximo parai
, e incluso con el complejo código matemático colocado dentro. Entonces, a menos que solo esté esperando unos pocos milisegundos, todavía parece que no hay forma de dormir con gracia en JS.Se puede hacer usando el método de suspensión de Java. Lo probé en FF e IE y no bloquea la computadora, no consume recursos ni causa interminables visitas al servidor. Parece una solución limpia para mí.
Primero debe cargar Java en la página y hacer que sus métodos estén disponibles. Para hacer eso, hice esto:
Entonces, todo lo que tiene que hacer cuando desea una pausa indolora en su JS es:
Donde xxx es el tiempo en milisegundos. En mi caso (a modo de justificación), esto era parte del cumplimiento de pedidos de back-end en una empresa muy pequeña y necesitaba imprimir una factura que tenía que cargarse desde el servidor. Lo hice cargando la factura (como página web) en un iFrame y luego imprimiendo el iFrame. Por supuesto, tuve que esperar hasta que la página se haya cargado por completo antes de poder imprimir, por lo que el JS tuvo que hacer una pausa. Lo logré haciendo que la página de la factura (en el iFrame) cambie un campo de formulario oculto en la página principal con el evento onLoad. Y el código en la página principal para imprimir la factura se veía así (partes irrelevantes cortadas para mayor claridad):
Entonces, el usuario presiona el botón, el script carga la página de la factura, luego espera, verificando cada cuarto de segundo para ver si la página de la factura ha terminado de cargarse, luego aparece el diálogo de impresión para que el usuario la envíe a la impresora. QED
fuente
Muchas de las respuestas no responden (directamente) a la pregunta, y esta tampoco ...
Aquí están mis dos centavos (o funciones):
Si desea funciones menos torpes que
setTimeout
ysetInterval
, puede envolverlas en funciones que simplemente invierten el orden de los argumentos y les dan nombres agradables:Versiones de CoffeeScript:
Luego puede usarlos bien con funciones anónimas:
Ahora se lee fácilmente como "después de N milisegundos, ..." (o "cada N milisegundos, ...")
fuente
Para el caso específico de querer espaciar un conjunto de llamadas que se ejecutan mediante un bucle, puede usar algo como el siguiente código con prototipo. Sin prototipo, puede sustituir la función de retraso con setTimeout.
fuente
Si estás en node.js, puedes echar un vistazo a las fibras : una extensión nativa de C para el nodo, una simulación de subprocesos múltiples.
Le permite hacer un real
sleep
de una manera que bloquea la ejecución en una fibra, pero no bloquea el hilo principal y otras fibras.Aquí hay un ejemplo reciente de su propio archivo Léame:
- y los resultados son:
fuente