Antworten:
Ab Knoten 10.17 verfügt stream.Readable über eine from
Methode zum einfachen Erstellen von Streams aus beliebigen iterierbaren Elementen (einschließlich Array-Literalen):
const { Readable } = require("stream")
const readable = Readable.from(["input string"])
readable.on("data", (chunk) => {
console.log(chunk) // will be called once with `"input string"`
})
Beachten Sie, dass mindestens zwischen 10.17 und 12.3 eine Zeichenfolge selbst iterierbar ist, also Readable.from("input string")
funktioniert, aber ein Ereignis pro Zeichen ausgibt . Readable.from(["input string"])
gibt ein Ereignis pro Element im Array aus (in diesem Fall ein Element).
Beachten Sie auch, dass in späteren Knoten (wahrscheinlich 12.3, da in der Dokumentation angegeben ist, dass die Funktion damals geändert wurde) die Zeichenfolge nicht mehr in ein Array eingeschlossen werden muss.
https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options
Da @substack mich in #node korrigiert hat, erleichtert die neue Streams-API in Node v10 dies:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
… Danach können Sie frei pfeifen oder auf andere Weise an Ihren beabsichtigten Verbraucher weitergeben.
Es ist nicht so sauber wie der Resumer - Einzeiler , aber es vermeidet die zusätzliche Abhängigkeit.
( Update: In Version 0.10.26 bis Version 9.2.1 stürzt ein Aufruf push
direkt von der REPL-Eingabeaufforderung mit einer not implemented
Ausnahme ab, wenn Sie ihn nicht festgelegt haben _read
. Er stürzt nicht in einer Funktion oder einem Skript ab. Wenn Sie inkonsistent sind nervös, gehören die noop
.)
_read
Methode zum Abrufen von Daten aus der zugrunde liegenden Ressource bereitstellen ."
null
in den Puffer des Streams?
null
teilt dem Stream mit, dass er alle Daten gelesen und den Stream geschlossen hat
readable.push()
Methode soll nur von lesbaren Implementierern und nur innerhalb der readable._read()
Methode aufgerufen werden."
Verwenden Sie nicht die Antwort von Jo Liss. Es wird in den meisten Fällen funktionieren, aber in meinem Fall hat es mir gute 4 oder 5 Stunden Fehlersuche verloren. Hierfür sind keine Module von Drittanbietern erforderlich.
NEUE ANTWORT :
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
Dies sollte ein vollständig kompatibler lesbarer Stream sein. Sehen Sie hier für weitere Informationen auf , wie man richtig Ströme verwenden.
ALTE ANTWORT : Verwenden Sie einfach den nativen PassThrough-Stream:
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
})
Beachten Sie, dass das Ereignis 'close' nicht ausgegeben wird (was von den Stream-Schnittstellen nicht benötigt wird).
Erstellen Sie einfach eine neue Instanz des stream
Moduls und passen Sie sie Ihren Anforderungen an:
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
oder
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()
soll zumindest den Zielstrom zurückgeben.
Edit: Garths Antwort ist wahrscheinlich besser.
Mein alter Antworttext bleibt unten erhalten.
Um einen String in einen Stream zu konvertieren, können Sie eine Pause durch Strom:
through().pause().queue('your string').end()
Beispiel:
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
recht gut. Vielen Dank!
Dafür gibt es ein Modul: https://www.npmjs.com/package/string-to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
Eine andere Lösung besteht darin, die Lesefunktion an den Konstruktor von Readable zu übergeben (siehe lesbare Optionen für den Doc- Stream ).
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
Sie können nach der Verwendung an Rohr zum Beispiel
Ich hatte es satt, dies alle sechs Monate neu lernen zu müssen, und habe gerade ein npm-Modul veröffentlicht, um die Implementierungsdetails zu abstrahieren:
https://www.npmjs.com/package/streamify-string
Dies ist der Kern des Moduls:
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
ist das string
, was beim Aufruf an den Konstruktor übergeben werden muss und vom Stream als Daten ausgegeben wird. options
sind die typischen Optionen, die gemäß der Dokumentation an einen Stream übergeben werden können .
Laut Travis CI sollte es mit den meisten Versionen von Node kompatibel sein.
Hier ist eine ordentliche Lösung in 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 ist vom Typ Ente. Wenn Sie also nur die API eines lesbaren Streams kopieren , funktioniert dies einwandfrei. In der Tat können Sie wahrscheinlich die meisten dieser Methoden nicht implementieren oder sie einfach als Stubs belassen. Alles, was Sie implementieren müssen, ist das, was die Bibliothek verwendet. Sie können die vorgefertigte EventEmitter
Klasse von Node auch zum Behandeln von Ereignissen verwenden, sodass Sie dies nicht selbst implementieren müssen addListener
.
So können Sie es in CoffeeScript implementieren:
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'
Dann könnten Sie es so verwenden:
stream = new StringStream someString
doSomethingWith stream
stream.send()
TypeError: string is not a function at String.CALL_NON_FUNCTION (native)
new StringStream(str).send()
stream.Readable
wie von @Garth Kidd vorgeschlagen.
stream.Readable
existierte nicht, als ich diese Antwort schrieb.