Estou desenvolvendo um console como script para necessidades pessoais. Eu preciso fazer uma pausa por um longo período de tempo, mas, a partir da minha pesquisa, o node.js não tem como parar conforme necessário. Está ficando difícil ler as informações dos usuários após um período de tempo ... Eu vi alguns códigos por aí, mas acredito que eles precisam ter outro código dentro deles para que funcionem, como:
setTimeout(function() {
}, 3000);
No entanto, eu preciso de tudo após esta linha de código para executar após o período de tempo.
Por exemplo,
//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode.
Eu também vi coisas como
yield sleep(2000);
Mas o node.js não reconhece isso.
Como posso conseguir essa pausa prolongada?
javascript
node.js
yield
Christopher Allen
fonte
fonte
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Respostas:
A melhor maneira de fazer isso é dividir seu código em várias funções, assim:
É semelhante à solução do JohnnyHK , mas muito mais simples e fácil de estender.
fonte
debugger;
Uma nova resposta para uma pergunta antiga. Hoje (
janeiro de 2017junho de 2019) é muito mais fácil. Você pode usar a novaasync/await
sintaxe . Por exemplo:Para usarasync/await
imediatamente, sem instalar e plug-ins, é necessário usar o nó-v7 ou o nó-v8, usando o--harmony
sinalizadorAtualização junho de 2019: Ao usar as versões mais recentes do NodeJS, você pode usá-lo imediatamente. Não há necessidade de fornecer argumentos de linha de comando. Até o Google Chrome o suporta hoje.
Atualização em maio de 2020: em breve você poderá usar a
await
sintaxe fora de uma função assíncrona. No nível superior, como neste exemploA proposta está no estágio 3 . Você pode usá-lo hoje usando o webpack 5 (alpha),
Mais informações:
fonte
await
palavra - chave na frente desleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Para os fãs de oneliner como eu :)let sleep = require('util').promisify(setTimeout);
funciona no nó 7.6+ e melhora a legibilidadeA solução mais curta sem nenhuma dependência:
fonte
let sleep = require('util').promisify(setTimeout);
é três personagens mais tempo, mas reutilizável e mais legível imoresolve
vez dedone
. Ou sejaawait new Promise(resolve => setTimeout(resolve, 5000))
Coloque o código que você deseja executar após o atraso no
setTimeout
retorno de chamada:fonte
node-fibers
. Confira.Esta é uma técnica simples de bloqueio:
Está bloqueando na medida em que nada mais acontecerá no seu script (como retornos de chamada). Mas como esse é um script de console, talvez seja o que você precisa!
fonte
wait
, bloqueia e funciona para algum propósito de teste. Exatamente o que eu estava procurando.spin-wait
.No nó 7.6.0 ou superior
O nó suporta a espera nativamente:
se você pode usar funções assíncronas:
ou:
Nas versões mais antigas do nó (resposta original)
Eu queria um sono assíncrono que funcionasse no Windows e Linux, sem sobrecarregar minha CPU com um longo loop. Tentei o pacote de suspensão, mas ele não foi instalado na minha caixa do Windows. Acabei usando:
https://www.npmjs.com/package/system-sleep
Para instalá-lo, digite:
No seu código,
Funciona como um encanto.
fonte
Função de sono simples e elegante usando Javascript moderno
Sem dependências, sem retorno de chamada; é isso aí :-)
Considerando o exemplo dado na pergunta, é assim que dormimos entre dois logs do console:
A "desvantagem" é que sua função principal agora também precisa ser
async
. Mas, considerando que você já está escrevendo um código Javascript moderno, provavelmente você está (ou pelo menos deveria estar!) Usandoasync
/ emawait
todo o seu código, então isso realmente não é um problema. Todos os navegadores modernos hoje suportam .Fornecendo uma pequena visão da
sleep
função para aqueles que não estão acostumadosasync/await
e operadores de seta gorda, esta é a maneira detalhada de escrevê-la:No entanto, o uso do operador de seta gorda o torna ainda menor (e mais elegante).
fonte
async
tecla e deixando tudo o mesmo. Provavelmente é mais claro com oasync
pensamento.async
. Editou minha resposta com sua sugestão. Eu não acho que isso torna o código mais claro; por isso, eu recorreria ao JSDoc.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Você pode usar este site www.npmjs.com/package/sleep
fonte
MacOS
, mas encontra errosCentOS
devido a erros do node_gyp . Parece não ser portátil.Essa pergunta é bastante antiga, mas recentemente a V8 adicionou geradores que podem realizar o que o OP solicitou. Geralmente, os geradores são mais fáceis de usar para interações assíncronas com a assistência de uma biblioteca, como suspender ou executar com gen .
Aqui está um exemplo usando o suspend:
Leitura relacionada (por meio de autopromoção desavergonhada): Qual é o grande problema dos geradores? .
fonte
yield setTimeout(suspend.resume(), 10000);
--harmony
bandeira e, de acordo com node.green, estão pelo menos disponíveis sem sinalizadores desde a v4.8.4: node.green/#ES2015-functions-generators-basic-functionality . Observe, no entanto, que aasync/await
sintaxe mais recente fornece uma solução melhor para isso agora, sem a necessidade de bibliotecas extras comosuspend
. Veja esta resposta para um exemplo: stackoverflow.com/a/41957152/376789 . As funções assíncronas estão disponíveis (sem sinalizadores) desde a v7.10.No Linux / nodejs, isso funciona para mim:
Está bloqueando, mas não é um ciclo de espera ocupado.
O tempo especificado é em segundos, mas pode ser uma fração. Não sei se outros sistemas operacionais têm um comando semelhante.
fonte
sleep
é praticamente onipresente e muito útil desde os primeiros dias do UNIX en.wikipedia.org/wiki/Sleep_%28Unix%29 . Apenas "não raro" os que talvez não existiria é windows (no entanto, há que você poderia tentarchild_process.spawnSync('timeout', ['/T', '10'])
Se você deseja "codificar golfe", você pode fazer uma versão mais curta de algumas das outras respostas aqui:
Mas, na verdade, a resposta ideal, na minha opinião, é usar a
util
biblioteca do Node e suapromisify
função, projetada exatamente para esse tipo de coisa (criando versões baseadas em promessas de coisas não baseadas em promessas anteriormente existentes):Em ambos os casos, você pode pausar simplesmente usando
await
para chamar suasleep
função:fonte
await
. Ele meio que cria um retorno de chamada, pausa as coisas e reinicia o código quando esse retorno de chamada. O retorno de chamada retorna com um valor, mas não nos preocupamos com isso neste caso, portanto, não resta nada à esquerdaawait
.Recentemente, criei uma abstração mais simples chamada wait.for para chamar funções assíncronas no modo de sincronização (com base nas fibras do nó). Há também uma versão baseada nos próximos Geradores ES6.
https://github.com/luciotato/waitfor
Usando wait.for , você pode chamar qualquer função nodejs assíncrona padrão, como se fosse uma função de sincronização, sem bloquear o loop de eventos do nó.
Você pode codificar sequencialmente quando precisar, o que é (suponho) perfeito para simplificar seus scripts para uso pessoal.
usando wait.for, seu código será:
Também qualquer função assíncrona pode ser chamada no modo Sincronizar . Veja os exemplos.
fonte
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
encontrei outros erros relacionados a propriedades indefinidas, etc. Então, eu também precisei copiá-los. Por que você não organiza o código de maneira que isso não seja necessário?Como o mecanismo javascript (v8) executa o código com base na sequência de eventos na fila de eventos, não é rigoroso que o javascript acione exatamente a execução após o tempo especificado. Ou seja, quando você define alguns segundos para executar o código posteriormente, o código de acionamento é puramente baseado na sequência na fila de eventos. Portanto, disparar a execução do código pode levar mais do que o tempo especificado.
Então o Node.js segue,
para executar o código posteriormente, em vez de setTimeout (). Por exemplo,
fonte
Com o ES6 suportando
Promise
s, podemos usá-los sem nenhum auxílio de terceiros.Em seguida, use-o assim:
Observe que a
doWhat
função se torna oresolve
retorno de chamada dentro donew Promise(...)
.Observe também que isso é sono ASSÍNCRONO. Não bloqueia o loop de eventos. Se você precisar bloquear o sono, use esta biblioteca que realiza o bloqueio do sono com a ajuda de ligações do C ++. (Embora a necessidade de um sono bloqueador no Node como ambientes assíncronos seja rara.)
https://github.com/erikdubbelboer/node-sleep
fonte
Este código acima é o efeito colateral do problema do inferno de retorno de chamada assíncrona do Javascript. Esta é também a razão pela qual acho que faz do Javascript uma linguagem útil no back-end. Na verdade, esta é a melhoria mais emocionante introduzida no Javascript moderno na minha opinião. Para entender completamente como ele funciona, como o gerador funciona precisa ser totalmente compreendido. A
function
palavra-chave seguida por a*
é chamada de função geradora em Javascript moderno. O pacote npmco
forneceu uma função runner para executar um gerador.Essencialmente, a função gerador forneceu uma maneira de pausar a execução de uma função com a
yield
palavra - chave, ao mesmo tempo,yield
em uma função geradora, permitindo a troca de informações entre o gerador e o chamador. Isso forneceu um mecanismo para o chamador extrair dados de umapromise
chamada assíncrona e passar os dados resolvidos de volta ao gerador. Efetivamente, ele faz uma chamada assíncrona síncrona.fonte
Este é um módulo com formato moment.js, com base na abordagem de bloqueio sujo sugerida por @ atlex2 . Use isso apenas para testes .
fonte
Se você apenas precisar suspender para fins de teste, a execução atual do encadeamento tente o seguinte:
fonte
simples, vamos esperar por 5 segundos para que algum evento aconteça (que seria indicado pela variável concluída configurada como true em outro lugar no código) ou quando o tempo limite expirar, verificaremos a cada 100 ms
fonte
Para algumas pessoas, a resposta aceita não está funcionando, encontrei esta outra resposta e está funcionando para mim: Como posso passar um parâmetro para um retorno de chamada setTimeout ()?
'olá' é o parâmetro que está sendo passado, você pode passar todos os parâmetros após o tempo limite. Obrigado a @Fabio Phms pela resposta.
fonte
Em vez de fazer todos esses setTimeout, sleep e muitas outras coisas, é melhor usar
fonte
As outras respostas são ótimas, mas pensei em usar um tato diferente.
Se tudo o que você está realmente procurando é diminuir a velocidade de um arquivo específico no linux:
nó myprog slowfile
Isso durará 1 segundo a cada cinco linhas. O programa do nó será tão lento quanto o gravador. Se estiver fazendo outras coisas, eles continuarão na velocidade normal.
O mkfifo cria um tubo primeiro a entrar, primeiro a sair. É o que faz isso funcionar. A linha perl escreverá tão rápido quanto você desejar. O $ | = 1 diz não armazenar em buffer a saída.
fonte
Eu montei, depois de ler as respostas nesta pergunta, uma função simples que também pode fazer um retorno de chamada, se você precisar:
fonte
Para mais informações sobre
você deve verificar o Redux-Saga . Mas é específico para sua escolha do Redux como sua estrutura de modelo (embora estritamente não seja necessário).
fonte