Dormir em JavaScript – atraso entre ações

Existe uma maneira que eu possa dormir em JavaScript antes de realizar outra ação?

Exemplo:

var a = 1+3; // Sleep 3 seconds before the next action here var b = a + 4; 

Você pode usar setTimeout para obter um efeito semelhante:

 var a = 1 + 3; var b; setTimeout(function() { b = a + 4; }, (3 * 1000)); 

Isso realmente não “adormece” JavaScript – apenas executa a function passada para setTimeout após uma certa duração (especificada em milissegundos). Embora seja possível escrever uma function sleep para JavaScript, é melhor usar setTimeout se possível, pois ela não congela tudo durante o período de suspensão.

Caso você realmente precise sleep() apenas para testar algo. Mas esteja ciente de que ele irá travar o navegador na maioria das vezes durante a debugging – provavelmente é por isso que você precisa disso de qualquer maneira. No modo de produção, comentarei essa function.

 function pauseBrowser(millis) { var date = Date.now(); var curDate = null; do { curDate = Date.now(); } while (curDate-date < millis); } 

Não use o new Date() no loop, a menos que você queira desperdiçar memory, poder de processamento, bateria e possivelmente a vida útil do seu dispositivo.

Versão ECMAScript 6, usando geradores com rendimento para “code blocking”:

Como a pergunta original foi postada há sete anos, não me incomodei em responder com o código exato, porque é muito fácil e já respondi. Isso deve ajudar em problemas mais complicados, como se você precisasse de pelo menos dois períodos de suspensão ou se estivesse planejando sequenciar a execução assíncrona. Sinta-se à vontade para modificá-lo para atender às suas necessidades.

 let sleeptime = 100 function* clock() { let i = 0 while( i <= 10000 ) { i++ console.log(i); // actually, just do stuff you wanna do. setTimeout( ()=> { clk.next() } , sleeptime ) yield } } let clk = clock() clk.next() 

Atualização 2018

O mais recente Safari, Firefox e Node.js agora também suportam async / await / promises.

Atualização de 2017

O JavaScript evoluiu desde que esta pergunta foi feita e agora tem funções de gerador, e o novo async / await / Promise está sendo implementado. Abaixo, há duas soluções, uma com function de gerador que funcionará em todos os navegadores modernos e outra com o novo async / wait que ainda não é suportado em todos os lugares.

Usando uma function geradora:

 'use strict'; let myAsync = (g) => (...args) => { let f, res = () => f.next(), sleep = (ms) => setTimeout(res, ms); f = g.apply({sleep}, args); f.next(); }; let myAsyncFunc = myAsync(function*() { let {sleep} = this; console.log("Sleeping"); yield sleep(3000); console.log("Done"); }); myAsyncFunc(); 

Se você quiser funções menos desajeitadas do que setTimeout e setInterval , você pode envolvê-las em funções que apenas inverter a ordem dos argumentos e dar a eles nomes interessantes:

 function after(ms, fn){ setTimeout(fn, ms); } function every(ms, fn){ setInterval(fn, ms); } 

Versões CoffeeScript:

 after = (ms, fn)-> setTimeout fn, ms every = (ms, fn)-> setInterval fn, ms 

Você pode então usá-los bem com funções anônimas:

 after(1000, function(){ console.log("it's been a second"); after(1000, function(){ console.log("it's been another second"); }); }); 

Agora ele lê facilmente como “após N milissegundos, …” (ou “a cada N milissegundos, …”)

Existem várias maneiras de resolver esse problema. Se usarmos a function setTimeout , vamos conhecê-la primeiro. Esta function possui três parâmetros: function ou code , delay (em milissegundos) e os parameters . Como a function ou parâmetro de código é obrigatório, os outros são opcionais. Uma vez que você não tenha inserido o atraso , ele será definido como zero.

Para mais detalhes sobre o setTimeout() acesse este link .

Versão simplificada:

 var a = 1 + 3; var b; console.log('a = ' + a); setTimeout(function(){ b = a + 4; console.log('b = ' + b); }, 1000); 

saída:
a = 4
24 -> Número identificador da lista de tempos limite ativos
b = 8

Usando o parâmetro pass:

 var a = 1 + 3; var b; console.log('a = ' + a); setTimeout(myFunction, 1000, a); function myFunction(a) { var b = a + 4; console.log('b = ' + b); } 

saída:
a = 4
25 -> Número identificador da lista de tempos limite ativos
b = 8

Suporte de Navegador:

 Chrome Firefox Edge Safari Opera
 1,0 1,0 4,0 1,0 4,0

Este é o meu modelo que mostra como “dormir” ou “DoEvents” em javascript usando uma function geradora (ES6). Código Comentado:

         

Outra maneira de fazer isso é usando Promise e setTimeout (observe que você precisa estar dentro de uma function e configurá-la como assíncrona com a palavra-chave async):

 async yourAsynchronousFunction () { var a = 1+3; await new Promise( (resolve, reject) => { setTimeout( () => { resolve(true); }, 3000); } var b = a + 4; }