概要
WHATWG Streams のことを何回かに分けて書く。Kyoto.js #11 の『 WHATWG Streams をためした 』という発表のために調べたものだ。発表だけで終わらせるのはもったいないので、再整理して共有する。
前回は『 WHATWG Streams の Stream と Pipe chain - Qiita 』。今回は (Underlying) Source と (Underlying) Sink のことを書く。
また Source / Sink については概要に留め、それぞれの使いかたなどの詳細は別途記載する。
Source
- データの発生源
- ReadableStream に wrap される
- Push / Pull の 2 種類の違いを吸収し、ひとつの interface で表す
- Push Source 例: TCP ソケット
- Pull Source 例: ファイルハンドル
- ReadableStream は queue の空き状況に応じて
pull()
してくれる - Source は ReadableStreamController を通じて ReadableStream に enqueue (これが push) できる
// イメージ
interface Source {
type?: 'bytes' | undefined;
start?(controller: ReadableStreamController): Promise<void> | undefined;
pull?(controller: ReadableStreamController): Promise<void> | undefined;
cancel?(reason: any): Promise<void> | undefined;
}
Sink
- データの行き先
- WritableStream に wrap される
- WritableStream は queue にあれば
write()
してくれる
// イメージ
interface Sink {
start?(controller: WritableStreamController): Promise<void> | undefined;
write?(chunk: any): Promise<void> | undefined;
close?(): Promise<void> | undefined;
abort?(reason: any): Promise<void> | undefined;
}
なぜ Source と Sink が重要か?
- なぜクラスとしては提供されない Source と Sink が重要なのか
- ReadableStream / WritableStream を継承するような使いかたはしない
- constructor に Source / Sink を指定する
new ReadableStream(source, options)
new WritableStream(sink, options)
- Source / Sink はクラスとして提供されないが、そのインタフェースをしばしば実装する
const data = [1, 2, 3];
new ReadableStream({ // **Source**
pull(controller) {
const chunk = data.shift();
controller.enqueue(chunk); // 1, 2, 3
}
})
.pipeThrough(new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk * 2);
}
}))
.pipeTo(new WritableStream({ // **Sink**
write(chunk) {
console.log(chunk); // 2, 4, 6
}
}));