Respostas:
No nó 10.17, stream.Readable possui um from
método para criar facilmente fluxos a partir de qualquer iterável (que inclui literais 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"`
})
Observe que pelo menos entre 10.17 e 12.3, uma sequência é iterável, portanto Readable.from("input string")
funcionará, mas emitirá um evento por caractere. Readable.from(["input string"])
emitirá um evento por item na matriz (nesse caso, um item).
Observe também que nos nós posteriores (provavelmente 12.3, já que a documentação diz que a função foi alterada), não é mais necessário agrupar a sequência em uma matriz.
https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options
Como o @substack me corrigiu no #node , a nova API de fluxos no nó v10 facilita isso:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
… Após o qual você pode canalizá- lo ou passá-lo livremente para o consumidor pretendido.
Não é tão limpo quanto o one-liner do resumerador , mas evita a dependência extra.
( Atualização: das v0.10.26 à v9.2.1 até agora, uma chamada para push
diretamente do prompt REPL falhará com uma not implemented
exceção se você não tiver definido _read
. Não falhará dentro de uma função ou script. Se a inconsistência o fizer nervoso, inclua o noop
.)
_read
método para buscar dados do recurso subjacente".
null
o buffer do fluxo?
null
diz ao stream que terminou de ler todos os dados e fechá
readable.push()
método deve ser chamado apenas pelos implementadores legíveis e somente de dentro do readable._read()
método".
Não use a resposta de Jo Liss. Funcionará na maioria dos casos, mas no meu caso, perdi uma boa localização de bug de 4 ou 5 horas. Não há necessidade de módulos de terceiros para fazer isso.
NOVA RESPOSTA :
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
Este deve ser um fluxo legível totalmente compatível. Veja aqui para mais informações sobre como usar fluxos corretamente.
RESPOSTA ANTIGA : Basta usar o fluxo PassThrough nativo:
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
})
Observe que o evento 'close' não é emitido (o que não é requerido pelas interfaces de fluxo).
Basta criar uma nova instância do stream
módulo e personalizá-lo de acordo com suas necessidades:
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
ou
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()
deve retornar o fluxo de destino, pelo menos.
Edit: A resposta de Garth é provavelmente melhor.
Meu texto de resposta antigo é preservado abaixo.
Para converter uma string para um fluxo, você pode usar uma pausa através de stream:
through().pause().queue('your string').end()
Exemplo:
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
funcionou muito bem. Obrigado!
Existe um módulo para isso: https://www.npmjs.com/package/string-to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
Outra solução é passar a função de leitura para o construtor de Readable ( opções legíveis do fluxo de documentos do cf )
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
após o uso do s.pipe, por exemplo,
Eu cansei de ter que reaprender isso a cada seis meses, então acabei de publicar um módulo npm para abstrair os detalhes da implementação:
https://www.npmjs.com/package/streamify-string
Este é o núcleo do 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
é o string
que deve ser passado para o construtor na invocação e será gerado pelo fluxo como dados. options
são as opções típicas que podem ser passadas para um fluxo, de acordo com a documentação .
De acordo com o Travis CI, ele deve ser compatível com a maioria das versões do nó.
Aqui está uma solução organizada no 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...')
O JavaScript é do tipo pato, portanto, se você apenas copiar a API de um fluxo legível , ele funcionará bem. De fato, você provavelmente não pode implementar a maioria desses métodos ou apenas deixá-los como stubs; tudo o que você precisa implementar é o que a biblioteca usa. Você pode usar a EventEmitter
classe pré-criada do Node para lidar com eventos também, para que você não precise implementar addListener
isso.
Veja como você pode implementá-lo no 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'
Então você pode usá-lo assim:
stream = new StringStream someString
doSomethingWith stream
stream.send()
TypeError: string is not a function at String.CALL_NON_FUNCTION (native)
quando eu usá-lo comonew StringStream(str).send()
stream.Readable
como a sugerida por @Garth Kidd.
stream.Readable
não existia quando escrevi esta resposta.