本文へ移動

終端処理 ​

.pipe() で組み立てたストリームは、終端処理が値を読み取り始めると実行されます。結果を配列に集める、1つの値に集約する、1件ずつ処理するなど、用途に合わせて選びます。

処理を選ぶ ​

目的API結果
全件を配列に集めるtoArray全要素の配列
合計など1つの値に集約するreduce最終的な累積値
結果を蓄積せず1件ずつ処理するforEachPromise<void>
条件に合う最初の値を得るfind最初の一致。なければ undefined
条件に合う値があるか調べるsome1件でも一致すれば true
全件が条件に合うか調べるevery全件が一致すれば true

これらは Promise を返し、stream.toArray({ signal }) のようなメソッドと toArray(source, { signal }) のような同名の関数の両方を使えます。関数形式は通常の同期・非同期 Iterable も受け取ります。

配列に集める・集約する ​

ts
import { from } from "mogami-stream";

export async function collectValues() {
  const numbers = from([1, 2, 3]);
  const values = await numbers.toArray(); // [1, 2, 3]
  const total = await numbers.reduce((sum, value) => sum + value, 0); // 6
  return { values, total };
}

toArray は出力をすべてメモリに保持するため有限の入力に使い、reduce は初期値から順番に集約して入力が空なら初期値を返します。上の例では配列をソースにしているため、同じストリームを読み直せます。

1件ずつ処理する ​

ts
export async function processValues<T>(
  input: Iterable<T> | AsyncIterable<T>,
  save: (value: T, signal: AbortSignal) => Promise<void>,
  signal: AbortSignal,
) {
  await from(input).forEach((value, { signal }) => save(value, signal), {
    signal,
  });
}

forEach はコールバックの完了を待ってから次の値を読み取ります。結果の配列は作りません。forEach と reduce のコールバックは逐次実行されるため、処理を並行化したい場合は上流に map(..., { concurrency }) を置きます。

条件で早期終了する ​

ts
export async function checkValues() {
  const numbers = from([1, 2, 3]);
  const first = await numbers.find((value) => value > 1); // 2
  const any = await numbers.some((value) => value > 2); // true
  const all = await numbers.every((value) => value > 0); // true
  return { first, any, all };
}

find は最初の一致、some は最初の一致、every は最初の不一致で上流を閉じます。入力が空の場合は、find が undefined、some が false、every が true を返します。

キャンセルと後処理 ​

{ signal } で実行をキャンセルできます。コールバックに渡される signal を I/O にも渡すと、実行中の処理にも停止を伝えられます。

終端処理は後処理が終わってから解決・拒否され、停止に対応しない I/O が残っている場合はその完了も待ちます。処理と後処理の両方が失敗した場合は、主な処理エラーを優先します。

手動で読み取る場合は for await...of、または iterate を使います。iterate は取得しただけでは実行せず、最初の next() で開始します。cancel()・return()・closed の使い分けはキャンセルと後処理を参照してください。

副次的なエラーも取得する場合は、結果と終了報告の取得レシピを参照してください。クリーンアップ完了前にタイムアウトを観測する方法も説明しています。