Відповіді:
З вузла 10.17, stream.Readable має from
метод легко створювати потоки з будь-якого ітерабельного (який включає літерали масиву):
const { Readable } = require("stream")
const readable = Readable.from(["input string"])
readable.on("data", (chunk) => {
console.log(chunk) // will be called once with `"input string"`
})
Зауважте, що принаймні між 10,17 та 12,3, рядок сам по собі є ітерабельним, тому він Readable.from("input string")
буде працювати, але випромінює одну подію на символ. Readable.from(["input string"])
передаватиме одну подію на елемент у масиві (у цьому випадку - один елемент).
Також зауважте, що в пізніших вузлах (ймовірно, 12.3, оскільки документація говорить, що функція була змінена тоді), більше не потрібно обертати рядок у масив.
https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options
Як @substack виправив мене в # node , новий API потоків у Node v10 полегшує це:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
… Після чого ви можете безперешкодно подати трубу або іншим чином передати її призначеному споживачеві.
Це не так чисто, як однорівневе відновлення , але це дозволяє уникнути додаткової залежності.
( Оновлення: від v0.10.26 до v9.2.1 поки що, виклик push
безпосередньо із запиту REPL припиняється, за not implemented
винятком випадків, якщо ви не встановили його _read
. Він не завершиться збоями всередині функції або сценарію. Якщо невідповідність робить вас нервувати, включати noop
.)
_read
спосіб отримання даних із базового ресурсу."
null
на буфер потоку?
null
повідомляє потоку, що він закінчив читати всі дані та закрити потік
readable.push()
Метод призначений викликати тільки читабельні виконавці, і лише зсередини readable._read()
методу."
Не використовуйте відповідь резюме Джо Лісса. Він працюватиме в більшості випадків, але в моєму випадку він втратив мені непогані 4 або 5 годин пошуку помилок. Для цього немає необхідності в сторонніх модулях.
НОВИЙ ВІДПОВІДЬ :
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
Це повинен бути повністю сумісний читабельний потік. Дивіться тут для отримання додаткової інформації про правильне використання потоків.
СТАРИЙ ВІДПОВІДЬ : Просто використовуйте рідний потік 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
})
Зауважте, що подія "закриття" не випромінюється (що не потрібно для інтерфейсів потоку).
Просто створіть новий примірник stream
модуля та налаштуйте його відповідно до ваших потреб:
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
або
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()
повинен повернути цільовий потік, як мінімум.
Редагувати: відповідь Гарта, ймовірно, краща.
Мій старий текст відповіді збережений нижче.
Щоб перетворити рядок у потік, ви можете використовувати паузу через потік:
through().pause().queue('your string').end()
Приклад:
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
працював досить добре. Дякую!
Для цього є модуль: https://www.npmjs.com/package/string-to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
Іншим рішенням є передача функції зчитування конструктору "Читабельний" (cf doc- read read-options )
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
ви можете після використання s.pipe для зразка
Я втомився від необхідності повторно вивчати це кожні півроку, тому я просто опублікував модуль npm, щоб відстежувати деталі реалізації:
https://www.npmjs.com/package/streamify-string
Це ядро модуля:
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
це те, string
що повинно бути передано конструктору після виклику і буде виведено потоком як дані. options
- це типові параметри, які можуть бути передані потоку відповідно до документації .
На думку Travis CI, він повинен бути сумісний з більшістю версій вузла.
Ось акуратне рішення в 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 набрав качку, тому якщо ви просто скопіюєте API для читання потоку , він буде працювати чудово. Насправді, ви, ймовірно, не можете реалізувати більшість цих методів або просто залишити їх як заглушки; все, що вам потрібно буде реалізувати, - це те, що використовує бібліотека. Ви також можете використовувати попередньо побудований EventEmitter
клас Node для вирішення подій, тому вам не доведеться самостійно реалізовувати addListener
та подібні.
Ось як можна реалізувати його в 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'
Тоді ви можете використовувати його так:
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
кшталт @Garth Kidd, який запропонував.