jQuery Academy · レッスン

Promiseの連結と合成

.then()と.pipe()を使って複数の非同期処理を連結し、$.when()で複数のPromiseの完了を待つ複雑なワークフローを構成する方法を学びます。

レッスン 2/311 ステップ

「Promiseの連結と合成」はCoddyKit上の無料jQuery Academyレッスンです。 これはレッスン2/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはjQuery Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 jQuery Academyコースには全3レッスンが含まれています。

非同期処理を順番に実行する

Web開発では、データの取得などの非同期タスクを特定の順序で実行する必要が生じることがよくあります。Promiseのチェーンを使うと、これをすっきり記述できます。

コールバックを入れ子にすると「コールバック地獄」につながることがありますが、処理を順番に連結すれば、コードが読みやすく保守しやすくなります。

.then()でチェーンする

.then()メソッドは、チェーン処理の基本となるものです。Deferred(またはPromise)が解決されると、その.then()コールバックが実行されます。このコールバックの戻り値は、チェーン内の次の.then()で使用できます。

コールバックが新しいDeferredを返した場合、チェーンはそのDeferredが解決されるまで待機してから次へ進みます。

単純な.then()チェーンの例

2つの非同期ステップをシミュレートする簡単な例を見てみましょう。2番目のステップは1番目のステップが完了した後にのみ実行され、1番目のステップのデータを使用します。

step1の結果('Data from Step 1')がstep2に渡されていることに注目してください。

function runChainExample() {
  let dfd1 = new $.Deferred();
  let dfd2 = new $.Deferred();

  setTimeout(() => {
    console.log("Step 1 complete!");
    dfd1.resolve("Data from Step 1");
  }, 500);

  dfd1.then(function(data1) {
    console.log("Received in Step 2: " + data1);
    setTimeout(() => {
      console.log("Step 2 complete!");
      dfd2.resolve("Processed " + data1);
    }, 300);
    return dfd2;
  }).then(function(data2) {
    console.log("Received in Final Step: " + data2);
    console.log("Chain finished!");
  });
}

$(document).ready(function() {
  runChainExample();
});

.then()チェーンでのデータの流れ

.then()コールバックの戻り値によって、次の.then()への入力が決まります。

  • Deferred以外の値を返すと、その値が次の.then()で解決された値になります。
  • Deferredオブジェクトを返すと、チェーンはそのDeferredが解決されるまで一時停止し、解決された値が次の.then()に渡されます。

変換に.pipe()を使用する

.then()が現在の標準である一方、jQueryの.Deferred()には.pipe()も用意されています。.then()に似ていますが、もともとは解決または拒否された値を変換したり、チェーンを継続するDeferredをフィルタリングしたりするために設計されました。

.pipe()を使用すると、変換された値で解決される新しいDeferredを返し、その値を次の段階へ「パイプ」できます。

.pipe()による変換の例

ここでは、.pipe()を使って最初の処理の結果を受け取り、変換(たとえば大文字への変換)してから、変換後の値を最後の.done()ハンドラーに渡します。

function runPipeExample() {
  let dfd = new $.Deferred();

  setTimeout(() => {
    console.log("Initial data ready.");
    dfd.resolve("hello world");
  }, 500);

  dfd.pipe(function(originalData) {
    console.log("Piping: Transforming data...");
    return originalData.toUpperCase(); // Transforms the value
  }).done(function(transformedData) {
    console.log("Final result: " + transformedData);
  });
}

$(document).ready(function() {
  runPipeExample();
});

$.when()で処理を組み合わせる

独立した複数の非同期タスクがあり、処理を続行する前にすべての完了を待つ必要がある場合はどうすればよいでしょうか。そのときに$.when()を使用します。

$.when()は、1つ以上のDeferredオブジェクト(またはPromise)を引数として受け取り、新しいDeferredを返します。この新しいDeferredは、入力されたDeferredがすべて解決された場合にのみ解決されます。

$.when()で並列タスクを実行する例

この例では、独立した2つのAJAXリクエスト(fetchUserとfetchPosts)をシミュレートします。$.when()を使い、両方が完了してから結合した結果をログに出力します。

処理が順番にではなく、並列に実行されることに注目してください。

function runWhenExample() {
  function fetchUser() {
    let dfd = new $.Deferred();
    setTimeout(() => {
      console.log("User data fetched.");
      dfd.resolve({ id: 1, name: "Alice" });
    }, 800);
    return dfd.promise();
  }

  function fetchPosts() {
    let dfd = new $.Deferred();
    setTimeout(() => {
      console.log("Posts data fetched.");
      dfd.resolve([{ id: 101, title: "Post 1" }, { id: 102, title: "Post 2" }]);
    }, 500);
    return dfd.promise();
  }

  $.when(fetchUser(), fetchPosts())
    .done(function(userData, postsData) {
      console.log("All data loaded!");
      console.log("User: ", userData);
      console.log("Posts: ", postsData);
    })
    .fail(function() {
      console.log("One or more tasks failed.");
    });
}

$(document).ready(function() {
  runWhenExample();
});

$.when()の結果にアクセスする

$.when()が返したDeferredが解決されると、その.done()または.then()コールバックは、入力された各Deferredの解決値を、$.when()に渡した順序で個別の引数として受け取ります。

これにより、すべてのデータが利用可能になった時点で、複数のソースから取得したデータを簡単に結合して処理できます。

Promiseチェーンのクイズ

次のjQueryコードを考えてみましょう。

let dfd1 = new $.Deferred();
let dfd2 = new $.Deferred();

dfd1.then(function(val) {
  return val + " World";
}).then(function(newVal) {
  console.log(newVal); // Line A
  return dfd2;
}).then(function() {
  console.log("Finished!"); // Line B
});

dfd1.resolve("Hello");
dfd2.resolve();

コンソールに出力される最終的な内容と、その順序はどうなりますか?

振り返り:チェーンと組み合わせ

複雑な非同期ワークフローを管理する方法を学びました。

  • .then()によるチェーン:処理を順番に実行し、ある段階の結果を次の段階へ渡します。
  • .pipe():チェーン内で値を変換したり、Deferredをマッピングしたりするための古いメソッドです。
  • $.when()による組み合わせ:複数の独立したDeferredが並列に完了するまで待機し、その結果を個別の引数として提供します。

これらのパターンは、堅牢で読みやすい非同期アプリケーションを構築するうえで重要です。

無料で開始

AI チューターと学ぶ JavaScript — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
22
レッスン
48

よくある質問

「Promiseの連結と合成」レッスンは無料ですか?

はい。「Promiseの連結と合成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、jQuery Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 jQuery Academyコースには全3レッスンが含まれています。

「Promiseの連結と合成」で何を学びますか?

.then()と.pipe()を使って複数の非同期処理を連結し、$.when()で複数のPromiseの完了を待つ複雑なワークフローを構成する方法を学びます。 ブラウザで直接実行するハンズオンコードでjQuery Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

jQuery Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのjQuery Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/3です。

「Promiseの連結と合成」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このjQuery Academyレッスンでコードを書いて実行できますか?

はい。すべてのjQuery Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Deferredオブジェクトを理解する
  2. Promiseの連結と合成
  3. 複数の非同期タスクの処理
← jQuery Academyに戻る