Respuestas:
Desde el nodo 10.17, stream.Readable tiene un from
método para crear fácilmente streams desde cualquier iterable (que incluye literales de matriz):
const { Readable } = require("stream")
const readable = Readable.from(["input string"])
readable.on("data", (chunk) => {
console.log(chunk) // will be called once with `"input string"`
})
Tenga en cuenta que al menos entre 10.17 y 12.3, una cadena es en sí misma iterable, por Readable.from("input string")
lo que funcionará, pero emite un evento por carácter.Readable.from(["input string"])
emitirá un evento por elemento en la matriz (en este caso, un elemento).
También tenga en cuenta que en los nodos posteriores (probablemente 12.3, ya que la documentación dice que la función se cambió entonces), ya no es necesario envolver la cadena en una matriz.
https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options
Como @substack me corrigió en #node , la nueva API de secuencias en el Nodo v10 lo hace más fácil:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
... después de lo cual puede canalizarlo libremente o, de lo contrario, pasarlo a su consumidor previsto.
No es tan limpio como el resumen de una línea, pero evita la dependencia adicional.
( Actualización: desde la v0.10.26 hasta la v9.2.1 hasta ahora, una llamada push
directa desde el indicador REPL se bloqueará con una not implemented
excepción si no la configuró _read
. No se bloqueará dentro de una función o un script. Si la inconsistencia lo hace nervioso, incluye el noop
.)
_read
método para obtener datos del recurso subyacente".
null
en el búfer de la secuencia?
null
le dice a la transmisión que ha terminado de leer todos los datos y cerrar la transmisión
readable.push()
método debe ser llamado solo por implementadores legibles, y solo desde dentro del readable._read()
método".
No use la respuesta del curriculum vitae de Jo Liss. Funcionará en la mayoría de los casos, pero en mi caso me perdió 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
Esto debería ser una transmisión legible totalmente compatible. Consulte aquí para obtener más información sobre cómo usar las transmisiones correctamente.
ANTIGUA RESPUESTA : Solo use la secuencia PassThrough nativa:
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 'close' no se emite (lo cual no es requerido por las interfaces de flujo).
Simplemente cree una nueva instancia del stream
módulo y personalícela 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');
pipe()
se supone que devuelve la secuencia de destino, al menos.
Editar: la respuesta de Garth es probablemente mejor.
Mi antiguo texto de respuesta se conserva a continuación.
Para convertir una cadena en una corriente, se puede utilizar una pausa a través de la secuencia:
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()
resumer
funcionó bastante bien. ¡Gracias!
Hay un módulo para eso: https://www.npmjs.com/package/string-to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
Otra solución es pasar la función de lectura al constructor de Readable (cf opciones de lectura de flujo de documentos )
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
puede después de usar en la tubería por ejemplo
Me cansé de tener que volver a aprender esto cada seis meses, así que publiqué 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 lo string
que se debe pasar al constructor al invocarlo, y el flujo lo 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.
Heres una solución ordenada en TypeScript:
import { Readable } from 'stream'
class ReadableString extends Readable {
private sent = false
constructor(
private str: string
) {
super();
}
_read() {
if (!this.sent) {
this.push(Buffer.from(this.str));
this.sent = true
}
else {
this.push(null)
}
}
}
const stringStream = new ReadableString('string to be streamed...')
JavaScript es de tipo pato, por lo que si solo copia una API legible , funcionará bien. De hecho, probablemente no pueda implementar la mayoría de esos métodos o simplemente dejarlos como apéndices; todo lo que necesitará implementar es lo que usa la biblioteca. Puedes usar el preconstruido de NodeEventEmitter
clase para lidiar con eventos, por lo que no tiene que implementaraddListener
usted mismo.
A continuación, se explica cómo 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()
TypeError: string is not a function at String.CALL_NON_FUNCTION (native)
cuando lo uso comonew StringStream(str).send()
stream.Readable
como la sugerida por @Garth Kidd.
stream.Readable
no existía cuando escribí esta respuesta.