Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

492
Visualizações
¿Por qué setInterval nunca se ejecuta, en mi código NodeJs que transmite un generador a un archivo?

Tengo esta situación en mi código NodeJs, que calcula las permutaciones (código de aquí ), pero no importa qué, no obtengo ningún resultado de setInterval .

 const { Readable } = require('stream'); const { intervalToDuration, formatDuration, format } = require('date-fns'); const { subsetPerm } = require('./permutation'); function formatLogs(counter, permStart) { const newLocal = new Date(); const streamTime = formatDuration(intervalToDuration({ end: newLocal.getTime(), start: permStart.getTime() })); const formattedLogs = `wrote ${counter.toLocaleString()} patterns, after ${streamTime}`; return formattedLogs; } const ONE_MINUTES_IN_MS = 1 * 60 * 1000; let progress = 0; let timerCallCount = 1; let start = new Date(); const interval = setInterval(() => { console.log(formatLogs(progress, start)); }, ONE_MINUTES_IN_MS); const iterStream = Readable.from(subsetPerm(Object.keys(Array.from({ length: 200 })), 5)); console.log(`Stream started on: ${format(start, 'PPPPpppp')}`) iterStream.on('data', () => { progress++; if (new Date().getTime() - start.getTime() >= (ONE_MINUTES_IN_MS * timerCallCount)) { console.log(`manual timer: ${formatLogs(progress, start)}`) timerCallCount++; if (timerCallCount >= 3) iterStream.destroy(); } }); iterStream.on('error', err => { console.log(err); clearInterval(interval); }); iterStream.on('close', () => { console.log(`closed: ${formatLogs(progress, start)}`); clearInterval(interval); }) console.log('done!');

Pero lo que encuentro es que imprime '¡hecho!' (esperado) y luego el script parece terminar, aunque si pongo un console.log en mi devolución de llamada on('data') obtengo datos impresos en la terminal. Pero incluso horas más tarde, console.log en setInterval nunca se ejecuta, ya que nada termina en el archivo, además de la salida de on('close',...) .

El registro de salida se parece a:

 > node demo.js Stream started on: Sunday, January 30th, 2022 at 5:40:50 PM GMT+00:00 done! manual timer: wrote 24,722,912 patterns, after 1 minute manual timer: wrote 49,503,623 patterns, after 2 minutes closed: wrote 49,503,624 patterns, after 2 minutes

Los temporizadores en la guía de nodos tienen una sección llamada ' dejando atrás los tiempos de espera ' que parecía relevante. Pero cuando pensé en usar interval.ref(); le dijo a la secuencia de comandos que no recolecte basura el objeto hasta que se llame a .unref() en el mismo objeto de tiempo de espera, en la segunda lectura eso no es del todo correcto y no hace la diferencia.

Estoy ejecutando esto usando npm como npm run noodle que solo apunta al archivo.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

El generador es síncrono y bloquea el bucle de eventos.

Readable.from procesa todo el generador de una sola vez, por lo que si el generador es sincrónico y de ejecución prolongada, bloquea el bucle de eventos.

Aquí está el código anotado que ejecuta:

 async function next() { for (;;) { try { const { value, done } = isAsync ? await iterator.next() : // our generator is not asynchronous iterator.next(); if (done) { readable.push(null); // generator not done } else { const res = (value && typeof value.then === 'function') ? await value : value; // not a thenable if (res === null) { reading = false; throw new ERR_STREAM_NULL_VALUES(); } else if (readable.push(res)) { // readable.push returns false if it's been paused, or some other irrelevant cases. continue; // we continue to the next item in the iterator } else { reading = false; } } } catch (err) { readable.destroy(err); } break; } }

Aquí está la API para readable.push , que explica cómo esto mantiene el generador en funcionamiento:

Devuelve: verdadero si se pueden seguir enviando fragmentos de datos adicionales; falso en caso contrario.

Nada le ha dicho a NodeJs que no continúe enviando datos, por lo que continúa.

Entre cada ejecución del ciclo de eventos, Node.js verifica si está esperando alguna E/S asíncrona o temporizadores y se apaga limpiamente si no hay ninguno.

Planteé esto como un problema de Github de NodeJs y terminé trabajando en esta solución:

 cosnt yieldEvery = 1e5; function setImmediatePromise() { return new Promise(resolve => setImmediate(resolve)); } const iterStream = Readable.from(async function* () { let i = 0 for await (const item of baseGenerator) { yield item; i++; if (i % yieldEvery === 0) await setImmediatePromise(); } }());

Esto está parcialmente inspirado en este blog de snyk.io , que entra en más detalles sobre este tema.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda