Los flujos de Nodejs admiten la generación de un flujo de transformación a partir de una función de generador asíncrono. Como dicen los documentos:
los generadores asíncronos son efectivamente una construcción de flujo de nivel de idioma de primera clase en este punto 1
const tf = stream.Duplex.from(async function* (source) { for await (const chunk of source) yield chunk; }); Sin embargo, parece no admitir ningún argumento de options , en contraste con muchos otros métodos de construcción de flujos. Por ejemplo, objectMode aparentemente está codificado en true 2 , pero surgen problemas similares para, por ejemplo highWaterMark . Los documentos dicen:
Intentar cambiar un flujo existente al modo objeto no es seguro 3
(nada de apagarlo)
Por lo tanto, el parámetro de options que falta es confuso para mí.
Quizás haya razones por las que tales flujos siempre deberían estar en modo objeto, pero no los veo. Similar a, por ejemplo, flujos legibles, un transformador como el siguiente tiene mucho sentido para mí (operación xor para fines de demostración, imagine, por ejemplo, desinflar):
const tf = stream.Duplex.from(async function* (source) { for await (const chunk of source) { for (let i = 0; i < chunk.length; i++) chunk[i] ^= 0x7C; yield chunk; } }); Tampoco pude encontrar nada potencialmente difícil sobre agregar un parámetro de options . Por lo tanto:
¿Hay alguna forma de cambiar las opciones al crear flujos de esta manera? (si no, ¿por qué?)
La ruta de ejecución cuando se usa Duplex.from y Readable.from está codificada de forma highWaterMark: 1 y objectMode: true en el código fuente del nodo . La implementación de cómo se crean los dúplex a partir de varias fuentes de datos está aquí .
Tenga en cuenta que el uso de .from() no cambia el hecho de que la fuente de la transmisión es un generador (asincrónico), y los generadores procesan una parte de los datos a la vez y se ejecutan hasta que se produce. En consecuencia, establecer una highWaterMark > 1 sería como introducir una matriz en el generador que consume de manera preventiva los elementos para procesar a continuación. Esto no tiene sentido. En cambio, se espera que los generadores procesen secuencialmente los elementos de un iterable, uno a la vez.
El mismo argumento se aplica a objectMode: true . El generador procesa secuencialmente elementos iterables en lugar de leer fragmentos de un búfer de bytes. El generador recibe estos elementos como entradas en lugar de obtener una porción de bytes de un búfer.
Por lo tanto, para los casos de uso en los que la entrada es un flujo continuo de bytes, se pueden usar las API de nivel inferior stream.Readable , stream.Writable y stream.Duplex .