読み込み中...

JavaScriptのyieldを使いこなす5つの方法

JavaScriptのyieldを分かりやすく解説する記事のサムネイル画像 JS
この記事は約7分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

JavaScriptのyieldを使いこなすことができれば、より効率的なコードを書くことができるようになります。

この記事では、初心者にも分かりやすくJavaScriptのyieldの使い方、サンプルコード、注意点と対処法、そして応用例を徹底解説していきます。

●JavaScriptのyieldとは

yieldは、JavaScriptのジェネレータ関数内で使用される特殊なキーワードです。

これを使用することで、ジェネレータ関数の途中で一時停止し、値を返すことができます。

また、再開時には停止した箇所から処理を続けることができます。

○yieldの基本

ジェネレータ関数は、function*という特殊な構文で定義されます。この関数内でyieldを使用することができます。

ジェネレータ関数はイテレータを返し、このイテレータを使って関数の実行を制御することができます。

●yieldの使い方

それでは、実際にyieldを使ってみましょう。

いくつかサンプルコードを紹介します。

○サンプルコード1:ジェネレータ関数の基本

このコードでは、ジェネレータ関数を定義し、yieldを使って値を返しています。

この例では、1から3までの数値を順番に返しています。

function* myGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const iterator = myGenerator();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

○サンプルコード2:非同期処理とyieldを組み合わせる

このコードでは、非同期処理を行う関数をジェネレータ関数でラップし、yieldを使って非同期処理が完了するまで待機しています。

function* asyncGenerator() {
  const result = yield new Promise(resolve => setTimeout(() => resolve('結果'), 1000));
  console.log(result);
}

function execute(generator) {
  const iterator = generator();
  function process(iteration) {
    if (!iteration.done) {
      iteration.value.then(result => process(iterator.next(result)));
    }
  }
  process(iterator.next());
}

execute(asyncGenerator);

○サンプルコード3:yieldとPromiseを使った非同期処理

このコードでは、Promise.allを使って複数の非同期処理を一度に実行し、すべての非同期処理が完了するまで待機してから結果を表示しています。

function* asyncGenerator() {
  const results = yield Promise.all([
    new Promise(resolve => setTimeout(() => resolve('結果1'), 1000)),
    new Promise(resolve => setTimeout(() => resolve('結果2'), 2000)),
    new Promise(resolve => setTimeout(() => resolve('結果3'), 3000))
  ]);
  console.log(results);
}

function execute(generator) {
  const iterator = generator();
  function process(iteration) {
    if (!iteration.done) {
      iteration.value.then(result => process(iterator.next(result)));
    }
  }
  process(iterator.next());
}

execute(asyncGenerator);

●yieldの応用例

次に、yieldの応用例をいくつか紹介します。

○サンプルコード4:yieldを使ったイテレータの実装

このコードでは、ジェネレータ関数を使って独自のイテレータを実装しています。

この例では、与えられた配列を逆順にイテレートするイテレータを作成しています。

function* reverseIterator(arr) {
  for (let i = arr.length - 1; i >= 0; i--) {
    yield arr[i];
  }
}

const arr = [1, 2, 3, 4, 5];
const iterator = reverseIterator(arr);

for (const value of iterator) {
  console.log(value); // 5, 4, 3, 2, 1 を順に出力
}

○サンプルコード5:yieldを活用した独自の制御構造

このコードでは、yieldを使って独自の制御構造を実現しています。

この例では、特定の条件を満たすまで処理を繰り返す制御構造を作成しています。

function* until(conditionFunc, generatorFunc) {
  while (!conditionFunc()) {
    yield* generatorFunc();
  }
}

let count = 0;
function increment() {
  count += 1;
}

function* counter() {
  yield increment();
}

function isGreaterThan5() {
  return count > 5;
}

for (const _ of until(isGreaterThan5, counter)) {
  console.log(count); // 1, 2, 3, 4, 5, 6 を順に出力
}

●注意点と対処法

yieldはジェネレータ関数内でのみ使用できます。

通常の関数内で使用しようとすると、SyntaxErrorが発生します。

また、ジェネレータ関数内でも、オブジェクトリテラル内や、関数リテラル内では使用できません。

●カスタマイズ方法

yieldを利用したコードは、他の関数やオブジェクトと組み合わせることで、さまざまな形でカスタマイズすることができます。

例えば、独自の非同期制御構造やデータ処理パターンを実現することが可能です。

また、yieldを使ったジェネレータ関数をライブラリやフレームワークと組み合わせて、より高度な機能を実現することもできます。

カスタマイズの際には、まず自分のニーズに合わせて、どのような機能や制御構造を実現したいかを明確にしましょう。

まとめ

この記事では、JavaScriptのyieldについて、その使い方や応用例を紹介しました。

yieldはジェネレータ関数内で使用できる特殊なキーワードで、関数の途中で一時停止したり、値を返したりすることができます。

また、非同期処理や独自の制御構造の実装に役立ちます。

yieldを使いこなすことで、より効率的なコードを書くことができるようになります。

ぜひ、この記事で紹介したサンプルコードを参考に、自分のプロジェクトでyieldを活用してみてください。