Existe uma maneira melhor de projetar um sleep
em JavaScript do que a seguinte pausecomp
função ( extraída daqui )?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
Esta não é uma duplicata do sono em JavaScript - atraso entre ações ; Eu quero um sono real no meio de uma função, e não um atraso antes que um pedaço de código seja executado.
javascript
sleep
fmsf
fonte
fonte
Respostas:
Atualização 2017 - 2019
Desde 2009, quando essa pergunta foi feita, o JavaScript evoluiu significativamente. Todas as outras respostas agora estão obsoletas ou excessivamente complicadas. Aqui está a melhor prática atual:
É isso.
await sleep(<duration>)
.Ou como uma linha:
Observe que,
await
só pode ser executado em funções prefixadas com aasync
palavra - chave ou no nível superior do seu script em alguns ambientes (por exemplo, o console do Chrome DevTools ou o Runkit).await
pausa apenas aasync
função atualDois novos recursos de JavaScript ajudaram a escrever essa função "sleep":
async/await
recurso permite que o código aguarde explicitamente a promessa de liquidação (resolução ou rejeição).Compatibilidade
async
/await
desembarcou na V8 e foi ativado por padrão desde o Chrome 55 (lançado em dezembro de 2016)Se por algum motivo estranho você estiver usando Node mais velho do que 7 (que chegou a final da vida ), ou são alvo navegadores antigos,
async
/await
ainda pode ser utilizada através de Babel (uma ferramenta que irá transpile JavaScript + novas funcionalidades em bom e velho JavaScript) , com otransform-async-to-generator
plugin.fonte
(Veja a resposta atualizada para 2016 )
Eu acho perfeitamente razoável querer executar uma ação, esperar e depois executar outra ação. Se você está acostumado a escrever em idiomas multithread, provavelmente terá a idéia de executar a execução por um período de tempo definido até que o thread seja ativado.
O problema aqui é que o JavaScript é um modelo baseado em evento de thread único. Enquanto, em um caso específico, pode ser bom esperar o mecanismo inteiro por alguns segundos; em geral, é uma prática ruim. Suponha que eu quisesse usar suas funções enquanto escrevia minhas próprias? Quando chamei seu método, meus métodos congelariam. Se o JavaScript puder, de alguma forma, preservar o contexto de execução da sua função, armazene-o em algum lugar, traga-o de volta e continue mais tarde, então o sono pode acontecer, mas isso seria basicamente o encadeamento.
Portanto, você está praticamente preso ao que os outros sugeriram - precisará dividir seu código em várias funções.
Sua pergunta é um pouco de uma escolha falsa, então. Não há como dormir da maneira que você deseja, nem deve buscar a solução sugerida.
fonte
sleep()
não é possível em JS e que na maioria das vezes existem maneiras melhores de fazer as coisas. Mas eu ainda consideraria a maneira como o mecanismo vincula todas as coisas como uma falha de design; não há razão para que o idioma não possa ter umasleep()
função limitada a um script, página ou função específica sem que o mecanismo atrapalhe a CPU e congele o aplicativo como um maníaco. É 2015 e você não deve conseguir travar um navegador da web inteirowhile(1)
. Temos Flash para coisas assim.Em JavaScript, reescrevo todas as funções para que possam terminar o mais rápido possível. Você deseja que o navegador volte ao controle para que ele possa fazer alterações no seu DOM.
Toda vez que eu queria dormir no meio da minha função, eu refatorava para usar a
setTimeout()
.Editar
O sono infame, ou atraso, função em qualquer idioma é muito debatido. Alguns dirão que sempre deve haver um sinal ou retorno de chamada para disparar uma determinada funcionalidade, outros argumentarão que às vezes um momento arbitrário de atraso é útil. Eu digo que cada uma delas e uma regra nunca podem ditar nada neste setor.
Escrever uma função de suspensão é simples e ainda mais utilizável com o JavaScript Promises:
fonte
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
Somente para debug / dev , eu posto isso se for útil para alguém
Coisas interessantes, no Firebug (e provavelmente em outros consoles js), nada acontece depois de pressionar enter, somente após a duração do sono especificada (...)
Exemplo de uso:
fonte
only for debug/dev
... rolleyesEu concordo com os outros pôsteres, um sono agitado é apenas uma má idéia.
No entanto, setTimeout não sustenta a execução, ele executa a próxima linha da função imediatamente após o tempo limite ser SET, não após o tempo limite expirar, para que não realize a mesma tarefa que um sono realizaria.
A maneira de fazer isso é desmembrar sua função nas partes antes e depois.
Verifique se os nomes das funções ainda descrevem com precisão o que cada peça está fazendo (IE GatherInputThenWait e CheckInput, em vez de funcPart1 e funcPart2)
Editar
Esse método atinge o objetivo de não executar as linhas de código que você decide até APÓS o tempo limite, enquanto ainda retorna o controle ao PC cliente para executar o que quer que esteja na fila.
Editar mais
Como apontado nos comentários, isso absolutamente NÃO FUNCIONA em um loop. Você pode fazer alguns hackers (feios) extravagantes para fazê-lo funcionar em um loop, mas, em geral, isso resultará em um código espaguete desastroso.
fonte
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
efor(var X = 0; X < 3;X++) { foo(X); }
- o valor de X é passado para ofoo
qual é reutilizado com o nomeindex
quandofoo_continue
é chamado.console.log()
interiorfoo_continue()
na versão setTimeout e você obterá o mesmo resultado.Por amor a $ DEITY, por favor, não faça uma função de espera de ocupado.
setTimeout
esetInterval
faça tudo o que você precisa.A cada intervalo de dois segundos, oculta o texto por um segundo. Isso mostra como usar setInterval e setTimeout para mostrar e ocultar o texto a cada segundo.
fonte
Sei que essa é uma pergunta antiga, mas se (como eu) você estiver usando Javascript no Rhino, poderá usar ...
fonte
Se você estiver usando jQuery, alguém realmente criou um plug-in "delay" que nada mais é do que um wrapper para setTimeout:
Você pode usá-lo em uma linha de chamadas de função conforme o esperado:
fonte
.delay()
faz parte do jQuery (embora com semântica diferente da implementação acima). api.jquery.com/delayTambém procurei a solução do sono (não o código de produção, apenas o dev / tests) e encontrei este artigo:
http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html
... e aqui está outro link com soluções do lado do cliente: http://www.devcheater.com/
Além disso, quando você estiver ligando
alert()
, seu código também será pausado, enquanto o alerta for exibido - é preciso encontrar uma maneira de não exibir o alerta, mas obter o mesmo efeito. :)fonte
Aqui está uma solução simples usando um XMLHttpRequest síncrono:
conteúdo de sleep.php:
Agora chame-o com: sleep (5);
fonte
setTimeout()
se isso funcionar, mas se isso significa desvendar 1000 linhas de retornos de chamada, isso pode começar a não parecer uma piada.sleep(300)
e o site demorar 150 ms para responder, o código javascript ficará em suspensão por 450ms. e se a conexão à Internet for perdida pelo navegador, ela funcionará por apenas 0ms. Portanto, não é a melhor soluçãoAqui está. Como o código diz, não seja um desenvolvedor ruim e use isso em sites. É uma função de utilitário de desenvolvimento.
fonte
async/await
, infelizmente, não responde, e precisamos usá-la obrigatoriamente.Eu pessoalmente gosto do simples:
então:
Estou usando o tempo todo para criar um tempo de carregamento falso enquanto cria scripts no P5js
fonte
Primeiro:
Defina uma função que você deseja executar assim:
Em seguida, planeje sua execução com o método setTimeout:
Observe duas coisas
fonte
verifique se a função de chamada é assíncrona
verificado e funcionando bem
fonte
A melhor solução para fazer as coisas parecerem o que a maioria das pessoas deseja é usar uma função anônima:
Provavelmente é o mais próximo que você pode chegar de algo que simplesmente faz o que você deseja.
Observe que, se você precisar de várias dormidas, isso pode ficar feio às pressas e você pode realmente precisar repensar seu design.
fonte
Para navegadores, concordo que setTimeout e setInterval são o caminho a percorrer.
Mas para o código do servidor, pode ser necessária uma função de bloqueio (por exemplo, para que você possa efetivamente sincronizar o encadeamento).
Se você estiver usando o node.js e o meteoro, pode ter encontrado as limitações do uso de setTimeout em uma fibra. Aqui está o código para suspensão do servidor.
Consulte: https://github.com/laverdet/node-fibers#sleep
fonte
Server may require a blocking function
... Não vejo como bloquear com força o único thread do Node e deixar todo o servidor sem resposta por vários segundos é uma boa idéia, mas tanto fazEncapsularia setTimeOut em uma promessa de consistência de código com outras tarefas assíncronas: Demo in Fiddle
Usado assim:
É fácil lembrar a sintaxe se você costumava usar o Promises.
fonte
Atualização de 2019 usando Atomics.wait
Deve funcionar no nó 9.3 ou superior.
Eu precisava de um cronômetro bastante preciso no Node.js e funciona muito bem para isso. No entanto, parece que há um suporte extremamente limitado nos navegadores.
Executou alguns benchmarks de timer de 10 segundos.
Com o setTimeout, recebo um erro de até 7000 microssegundos. (7ms)
Com o Atomics, meu erro parece permanecer abaixo de 600 microssegundos. (0.6ms)
Atualização 2020: Resumo
dos quais a página do lado do servidor, por exemplo
sleep.jsp
, se parecefonte
A maioria das respostas aqui são equivocadas ou, no mínimo, desatualizadas. Não há razão para o javascript ter que ser único e, de fato, não é. Hoje, todos os navegadores convencionais oferecem suporte a trabalhadores, antes disso, outros tempos de execução de javascript, como Rhino e Node.js, suportavam multithreading.
'Javascript é único encadeado' não é uma resposta válida. Por exemplo, executar uma função de suspensão em um trabalhador não bloqueia nenhum código em execução no encadeamento da interface do usuário.
Em tempos de execução mais recentes que suportam geradores e rendimento, pode-se trazer funcionalidade semelhante à função de suspensão em um único ambiente de encadeamento:
Essa imitação do sono é diferente de uma verdadeira função de sono, pois não bloqueia o encadeamento. É simplesmente uma adição à função atual setTimeout do javascript. Esse tipo de funcionalidade foi implementado no Task.js e deve funcionar hoje no Firefox.
fonte
sleep
usando vários trabalhadores. Se estiver usando o Node.js., as funções do gerador já estão implementadas e podem ser usadas conforme descrito. Os principais navegadores nem todos implementaram geradores a partir de hoje.Eu pesquisei / pesquisei algumas páginas da web em javascript sleep / wait ... e não há resposta se você quiser que o javascript "execute, atrase, execute" ... o que a maioria das pessoas conseguiu foi: "EXECUTAR, EXECUTAR (inútil coisas), EXECUTAR "ou" EXECUTAR, EXECUTAR + EXECUTAR atrasado "....
Então eu comi alguns hambúrgueres e fiquei pensando ::: aqui está uma solução que funciona ... mas você precisa cortar seus códigos de execução ... ::: sim, eu sei, isso é apenas uma refatoração mais fácil de ler .. . ainda...
//......................................... //Exemplo 1:
// .................................... // example2:
// ................. exemplo3:
// .............. example4:
fonte
fonte
A solução mais curta sem nenhuma dependência:
fonte
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
Você não pode dormir assim em JavaScript, ou melhor, não deveria. A execução de um loop sleep ou while fará com que o navegador do usuário seja interrompido até que o loop seja concluído.
Use um cronômetro, conforme especificado no link que você referenciou.
fonte
Um cenário em que você pode querer uma função sleep () em vez de usar setTimeout () é se você tiver uma função respondendo a um clique do usuário que acabará por abrir uma nova janela pop-up, ou seja, e você iniciou algum processamento que requer um curto período para concluir antes que o pop-up seja exibido. Mover a janela aberta para um fechamento significa que ela normalmente é bloqueada pelo navegador.
fonte
Entendo o objetivo de uma função de suspensão, se você precisar lidar com a execução síncrona. As funções setInterval e setTimeout criam um encadeamento de execução paralelo que retorna a sequência de execução ao programa principal, que é ineficaz se você precisar esperar por um determinado resultado. É claro que se pode usar eventos e manipuladores, mas em alguns casos não é o que se pretende.
fonte
Adicionando meus dois bits. Eu precisava de uma espera ocupada para fins de teste. Eu não queria dividir o código, pois isso daria muito trabalho, então é simples fazer isso por mim.
Não vejo nenhuma desvantagem em fazer isso e isso fez o truque para mim.
fonte
for
loops quase sempre é executado imediatamente, independentemente do valor máximo dei
, e mesmo com o código matemático complexo colocado dentro. Portanto, a menos que você esteja esperando apenas alguns milissegundos, ainda parece que não há como dormir normalmente em JS.Isso pode ser feito usando o método de suspensão do Java. Eu testei no FF e no IE e ele não bloqueia o computador, mastiga recursos ou causa inúmeros acessos ao servidor. Parece uma solução limpa para mim.
Primeiro, você deve carregar o Java na página e disponibilizar seus métodos. Para fazer isso, eu fiz o seguinte:
Então, tudo o que você precisa fazer quando deseja uma pausa indolor no seu JS é:
Onde xxx é o tempo em milissegundos. No meu caso (como justificativa), isso fazia parte do atendimento de pedidos de back-end em uma empresa muito pequena e eu precisava imprimir uma fatura que precisava ser carregada do servidor. Fiz isso carregando a fatura (como uma página da Web) em um iFrame e depois imprimindo o iFrame. Obviamente, tive que esperar até que a página estivesse totalmente carregada para poder imprimir, então o JS teve que fazer uma pausa. Eu consegui isso fazendo com que a página da fatura (no iFrame) alterasse um campo de formulário oculto na página pai com o evento onLoad. E o código na página pai para imprimir a fatura tinha esta aparência (peças irrelevantes cortadas para maior clareza):
Assim, o usuário aperta o botão, o script carrega a página da fatura e aguarda, verificando a cada quarto de segundo se a página da fatura terminou de carregar e, em seguida, aparece a caixa de diálogo de impressão para que o usuário a envie à impressora. QED.
fonte
Muitas das respostas não (diretamente) respondem à pergunta, e nem essa ...
Aqui estão meus dois centavos (ou funções):
Se você deseja menos funções desajeitadas que
setTimeout
esetInterval
, pode envolvê-las em funções que apenas invertem a ordem dos argumentos e lhes dão nomes agradáveis:Versões do CoffeeScript:
Você pode usá-los perfeitamente com funções anônimas:
Agora, lê-se facilmente como "após N milissegundos ..." (ou "a cada N milissegundo ...")
fonte
Para o caso específico de querer espaçar um conjunto de chamadas sendo executadas por um loop, você pode usar algo como o código abaixo com o protótipo. Sem protótipo, você pode substituir a função de atraso por setTimeout.
fonte
Se você estiver no node.js, poderá ver as fibras - uma extensão C nativa para o nó, uma simulação meio de multi-threading.
Ele permite que você faça um real de
sleep
maneira a bloquear a execução em uma fibra, mas não bloqueia o encadeamento principal e outras fibras.Aqui está um exemplo recente de seu próprio leia-me:
- e os resultados são:
fonte