read passthrough nodejs node example javascript string node.js stream inputstream

javascript - passthrough - ¿Cómo crear secuencias de cadena en Node.Js?



stream javascript (9)

Estoy usando una biblioteca, ya-csv , que espera un archivo o una secuencia como entrada, pero tengo una cadena.

¿Cómo convierto esa cadena en una secuencia en Node?


Como @substack me corrigió en #node , la nueva API de transmisiones en el Nodo v10 lo hace más fácil:

var Readable = require(''stream'').Readable; var s = new Readable(); s._read = function noop() {}; // redundant? see update below s.push(''your text here''); s.push(null);

... después de lo cual puede pipe libremente o pasarlo a su consumidor previsto.

No es tan limpio como el resumer una línea, pero evita la dependencia adicional.

( Actualización: en v0.10.26 hasta v9.2.1 hasta el momento, una llamada para push directamente desde el indicador REPL se bloqueará con una excepción not implemented si no configuró _read . No se bloqueará dentro de una función o un script. Si la inconsistencia te pone nervioso, incluye el noop .)



JavaScript está escrito en pato, por lo que si solo copia la API de una secuencia legible , funcionará perfectamente. De hecho, probablemente no pueda implementar la mayoría de esos métodos o simplemente dejarlos como talones; todo lo que necesitará implementar es lo que usa la biblioteca. También puede usar la clase EventEmitter para tratar los eventos, de modo que no tenga que implementar addListener y usted mismo.

Así es cómo puede implementarlo en CoffeeScript:

class StringStream extends require(''events'').EventEmitter constructor: (@string) -> super() readable: true writable: false setEncoding: -> throw ''not implemented'' pause: -> # nothing to do resume: -> # nothing to do destroy: -> # nothing to do pipe: -> throw ''not implemented'' send: -> @emit ''data'', @string @emit ''end''

Entonces podrías usarlo así:

stream = new StringStream someString doSomethingWith stream stream.send()


Me cansé de tener que volver a aprender esto cada seis meses, así que acabo de publicar un módulo npm para abstraer los detalles de implementación:

https://www.npmjs.com/package/streamify-string

Este es el núcleo del módulo:

const Readable = require(''stream'').Readable; const util = require(''util''); function Streamify(str, options) { if (! (this instanceof Streamify)) { return new Streamify(str, options); } Readable.call(this, options); this.str = str; } util.inherits(Streamify, Readable); Streamify.prototype._read = function (size) { var chunk = this.str.slice(0, size); if (chunk) { this.str = this.str.slice(size); this.push(chunk); } else { this.push(null); } }; module.exports = Streamify;

str es la string que se debe pasar al constructor al invocarse, y la corriente la generará como datos. options son las opciones típicas que se pueden pasar a una secuencia, según la documentación .

Según Travis CI, debería ser compatible con la mayoría de las versiones de nodo.


No use la respuesta de reanudación de Jo Liss. Funcionará en la mayoría de los casos, pero en mi caso me ha dejado una buena búsqueda de errores de 4 o 5 horas. No hay necesidad de módulos de terceros para hacer esto.

NUEVA RESPUESTA :

var Readable = require(''stream'').Readable var s = new Readable s.push(''beep'') // the string you want s.push(null) // indicates end-of-file basically - the end of the stream

Esta debería ser una transmisión legible completamente compatible. Consulte aquí para obtener más información sobre cómo usar las transmisiones de manera adecuada.

ANTIGUA RESPUESTA : Solo usa la transmisión nativa PassThrough:

var stream = require("stream") var a = new stream.PassThrough() a.write("your string") a.end() a.pipe(process.stdout) // piping will work as normal /*stream.on(''data'', function(x) { // using the ''data'' event works too console.log(''data ''+x) })*/ /*setTimeout(function() { // you can even pipe after the scheduler has had time to do other things a.pipe(process.stdout) },100)*/ a.on(''end'', function() { console.log(''ended'') // the end event will be called properly })

Tenga en cuenta que el evento ''cerrar'' no se emite (lo cual no es requerido por las interfaces de flujo).


Otra solución es pasar la función de lectura al constructor de lectura legible (ver opciones de lectura de flujo de doc)

var s = new Readable({read(size) { this.push("your string here") this.push(null) }});

usted puede después de usar en el tubo para ejemplo


Simplemente cree una nueva instancia del módulo de stream y personalícelo según sus necesidades:

var Stream = require(''stream''); var stream = new Stream(); stream.pipe = function(dest) { dest.write(''your string''); return dest; }; stream.pipe(process.stdout); // in this case the terminal, change to ya-csv

o

var Stream = require(''stream''); var stream = new Stream(); stream.on(''data'', function(data) { process.stdout.write(data); // change process.stdout to ya-csv }); stream.emit(''data'', ''this is my string'');


en coffee-script:

class StringStream extends Readable constructor: (@str) -> super() _read: (size) -> @push @str @push null

usarlo:

new StringStream(''text here'').pipe(stream1).pipe(stream2)


Editar: la respuesta de Garth es probablemente mejor.

Mi antiguo texto de respuesta se conserva a continuación.

Para convertir una cadena en una secuencia, puede usar una secuencia en pausa:

through().pause().queue(''your string'').end()

Ejemplo:

var through = require(''through'') // Create a paused stream and buffer some data into it: var stream = through().pause().queue(''your string'').end() // Pass stream around: callback(null, stream) // Now that a consumer has attached, remember to resume the stream: stream.resume()