Pregunta ¿Cuál es la versión de JavaScript de sleep ()?


¿Hay una mejor manera de diseñar un sleep en JavaScript que el siguiente pausecomp función (tomado 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 Dormir en JavaScript: demora entre las acciones; quiero un sueño real en el medio de una función, y no un retraso antes de que se ejecute un fragmento de código.


1519
2017-10-07 09:44


origen


Respuestas:


Actualización 2017

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:

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

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two second later');
}

demo();

Eso es todo. await sleep(<duration>).

Puedes probar este código en vivo en Runkit. Tenga en cuenta que,

  1. await solo se puede ejecutar en funciones con el prefijo async palabra clave. Runkit ajusta su código en una función asíncrona antes de ejecutarlo.
  2. await solo detiene la corriente async función

Dos nuevas funciones de JavaScript ayudaron a escribir esta función real de "suspensión":

Compatibilidad

Si por algún motivo está utilizando un Node anterior a 7 o está apuntando a navegadores antiguos, async/await todavía se puede usar a través de Babel (una herramienta que transpile JavaScript + nuevas características en JavaScript viejo sin formato), con el transform-async-to-generator enchufar. correr

npm install babel-cli --save

Crear .babelrc con:

{
  "plugins": [
    "transform-async-to-generator",
  ]
}

Luego ejecuta tu código con

node_modules/babel-cli/bin/babel-node.js sleep.js

Pero, nuevamente, no necesita esto si está utilizando el Nodo 7 o posterior, o si se está orientando a navegadores modernos.


1071



(Ver el respuesta actualizada para 2016)

Creo que es perfectamente razonable querer realizar una acción, esperar y luego realizar otra acción. Si está acostumbrado a escribir en lenguajes de subprocesos múltiples, probablemente tenga la idea de ceder la ejecución durante un período de tiempo determinado hasta que su subproceso 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, sería bueno tener todo el motor en espera durante unos segundos, en general es una mala práctica. Supongamos que quiero hacer uso de sus funciones mientras escribo las mías. Cuando llamé a su método, todos mis métodos se congelarían. Si JavaScript de alguna manera puede preservar el contexto de ejecución de su función, almacenarlo en algún lugar, luego traerlo de vuelta y continuar más tarde, entonces podría pasar el sueño, pero eso básicamente estaría enhebrado.

Entonces, estás bastante atrapado con lo que otros han sugerido: tendrás que dividir tu código en varias funciones.

Tu pregunta es un poco falsa, entonces. No hay forma de dormir de la manera que desee, ni debe buscar la solución que sugiere.


830



En JavaScript, reescribo todas las funciones para que finalicen lo antes posible. Desea que el navegador vuelva a tener el control para que pueda modificar su DOM.

Cada vez que quería dormir en el medio de mi función, refactorizaba para usar un setTimeout().

Voy a editar esta respuesta porque me pareció útil:

La infame función de dormir o retrasar en cualquier idioma es muy debatida. 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 de demora arbitrario. Digo que para cada uno su propia regla y una nunca pueden dictar nada en esta industria.

Escribir una función de suspensión es simple e incluso se puede utilizar con las promesas de JavaScript:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

590



Solo para depuración / dev , Publico esto si es útil para alguien

Algo interesante, en Firebug (y probablemente otras consolas js), no pasa nada después de presionar enter, solo después de la duración especificada (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Ejemplo de uso:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }

269



Estoy de acuerdo con los otros carteles, un sueño ocupado es solo una mala idea.

Sin embargo, setTimeout no mantiene la ejecución, sino que ejecuta la siguiente línea de la función inmediatamente después de que se agote el tiempo de espera, no después de que expire el tiempo de espera, por lo que no se logra la misma tarea que un sueño.

La forma de hacerlo es dividir tu función en antes y después de las partes.

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

Asegúrese de que los nombres de sus funciones todavía describan con precisión lo que hace cada pieza (I.E. 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 decide hasta DESPUÉS de su tiempo de espera, mientras sigue devolviendo el control a la PC del 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 ciclo. Podrías hacer un poco de piratería (fea) para hacer que funcione en un bucle, pero en general eso solo creará un desastroso código de spaghetti.


164



Por el amor de $ DEITY, no hagas una función de espera ocupado. setTimeout y setInterval haz todo lo que necesites


113



Sé que esta es una pregunta un poco vieja, pero si (como yo) estás usando Javascript con Rhino, puedes usar ...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}

109



Si usa jQuery, alguien realmente creó un complemento de "retraso" que no es más que un contenedor para setTimeout:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// -  2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

A continuación, puede usarlo en una fila de llamadas a funciones como se esperaba:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');

65



También busqué una solución de suspensión (no para el código de producción, solo para dev / tests) 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 llamas alert(), su código también estará en pausa, mientras se muestra la alerta, necesita encontrar una forma de no mostrar alerta pero obtener el mismo efecto. :)


42



Aqui tienes. Como dice el código, no seas un mal desarrollador y utiliza esto en los sitios web. Es una función de utilidad de desarrollo.

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}

28