JavaScriptでPromiseを使う方法|基礎から実例まで

※本サイトにはプロモーション・広告が含まれています。

(最終更新月:2023年11月)

✔以下のような方々へ向けて作成されております

「Javascriptプロミスが何なのか分からない」

「Javascriptプロミスの実装方法について知りたい」

「Javascriptプロミスの活用例を見て理解を深めたい」

✔当記事で得られる知識

  • Javascriptプロミスの概念
  • Javascriptプロミスの実装方法とその応用
  • Javascriptプロミスの具体的な活用例

当記事では、Javascriptプロミスの基礎から、さまざまなシチュエーションでの適切な使い方まで、現実に即した例を交えながら丁寧に解説いたします。

最後までお付き合い頂けますと幸いです。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

Promiseの基本 – その働きと重要性を理解する

こちらでは、Promiseの基本的な動作と、なぜそれが重要なのかを詳しく見ていきましょう。

Promiseの基本を理解することで、非同期処理の流れとその管理方法についての理解が深まります。

  • JavaScriptと非同期処理 – Promiseがなぜ必要か
  • 手続きの’お約束’ – Promiseの仕組み
  • Promiseの三つの状態 – 理解と適用

JavaScriptと非同期処理 – Promiseがなぜ必要か

元々のJavaScriptは、ブラウザ内での小さなスクリプトを実行するための言語。

しかし時間が経つにつれて、JavaScriptの役割は大きく変わり、サーバーサイドの処理や大規模なアプリケーションの開発にも使用されるようになりました。

このような背景から、非同期処理の管理が必要となり、Promiseが導入されたのです。

手続きの’お約束’ – Promiseの仕組み

Promiseは、文字通り「約束」を表すもの。

非同期処理が成功した場合や失敗した場合に、それぞれの結果を「約束」するという仕組みです。

具体的には、非同期処理が成功した場合にはresolveが、失敗した場合にはrejectが呼び出されます。

const promise = new Promise((resolve, reject) => {
    // 非同期処理
    if (/* 処理が成功 */) {
        resolve('成功!');
    } else {
        reject('失敗...');
    }
});

Promiseの三つの状態 – 理解と適用

Promiseには三つの状態があります。

  • pending(保留中)
  • fulfilled(完了)
  • rejected(拒否)。

Promiseが作成された直後の状態はpendingです。

非同期処理が成功するとfulfilledに、失敗するとrejectedに遷移します。

これらの状態遷移は一方向であり、一度fulfilledrejectedになると、その後の状態は変わりません。

Promiseの書き方 – 初心者向けガイド

こちらでは、Promiseの基本的な書き方を学び、実際に非同期処理を行う方法を解説していきます。

Promiseを活用した非同期処理の基本を身につけましょう。

  • Promiseインスタンスの作成
  • resolveとその使い方
  • rejectとその使い方
  • メソッドチェーンの理解と作成

Promiseインスタンスの作成

Promiseを使用するには、まず新しいPromiseインスタンスの作成が必要です。

このインスタンスは、非同期処理を実行する関数を引数として受け取ります。

const myPromise = new Promise((resolve, reject) => {
    // 非同期処理をここに書く
});

resolveとその使い方

非同期処理が成功した場合、resolve関数を呼び出してPromiseをfulfilled状態にします。

この関数は、非同期処理の結果を引数として受け取ることができます。

const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功!');
    }, 1000);
});

rejectとその使い方

非同期処理が失敗した場合、reject関数を呼び出してPromiseをrejected状態にします

この関数も、エラー情報などのデータを引数として受け取るものです。

const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error('何かがうまくいかなかった...'));
    }, 1000);
});

メソッドチェーンの理解と作成

Promiseは、.then().catch()といったメソッドをチェーンして使用できます。

これにより、非同期処理の結果に基づいてさらに処理を続けられるのです。

myPromise
    .then(result => {
        console.log(result);  // '成功!'
    })
    .catch(error => {
        console.error(error);  // Error: 何かがうまくいかなかった...
    });

Promiseの応用 – 高度なテクニック

こちらでは、Promiseの高度な使用方法やテクニックについてご覧ください。

より複雑な非同期処理のシナリオに対応できるようになります。

  • Promise連鎖の作り方
  • Thenableを適切に使う方法
  • Promiseを並行処理する方法

Promise連鎖の作り方

Promiseの強力な特性のひとつは、複数の非同期処理を順番に実行するための「連鎖」を作成できることです。

.then()メソッドを使用することで、前の非同期処理の結果を次の非同期処理に渡せます。

const step1 = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('ステップ1完了');
        }, 1000);
    });
};

const step2 = (message) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(`${message} -> ステップ2完了`);
        }, 1000);
    });
};

step1()
    .then(result => step2(result))
    .then(finalResult => {
        console.log(finalResult);  // 'ステップ1完了 -> ステップ2完了'
    });

Thenableを適切に使う方法

Thenableは、.then()メソッドを持つオブジェクトのことです。

Promiseとは異なるオブジェクトでも、.then()メソッドを持っていれば、Promiseのように扱えます。

const myThenable = {
    then(callback) {
        callback('Thenableからのデータ');
    }
};

Promise.resolve(myThenable)
    .then(data => {
        console.log(data);  // 'Thenableからのデータ'
    });

Promiseを並行処理する方法

複数のPromiseを同時に実行し、すべてのPromiseが完了したときに何らかの処理をおこないたい場合、Promise.all()を使用します。

const promise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve('Promise 1 完了');
    }, 1000);
});

const promise2 = new Promise((resolve) => {
    setTimeout(() => {
        resolve('Promise 2 完了');
    }, 2000);
});

Promise.all([promise1, promise2])
    .then(results => {
        console.log(results);  // ['Promise 1 完了', 'Promise 2 完了']
    });

Promiseの詳細解説 – 用語の解説

こちらでは、Promiseに関連する用語や概念について詳しく見ていきましょう。

Promiseの背後にある仕組みや理論を深く理解できます。

  • コンストラクタの詳細
  • Promiseを活用するための静的メソッド一覧
  • インスタンスプロパティとその利用
  • インスタンスメソッドとその利用

コンストラクタの詳細

Promiseコンストラクタは、新しいPromiseオブジェクトを生成します。

このコンストラクタでは、ひとつの引数、実行関数が必要です。

この実行関数自体は、resolverejectの2つの引数を取ります。

const promise = new Promise((resolve, reject) => {
    // 非同期処理
    if (/* 処理が成功 */) {
        resolve('成功!');
    } else {
        reject('失敗...');
    }
});

Promiseを活用するための静的メソッド一覧

Promiseには、いくつかの便利な静的メソッドがあります。

  • Promise.resolve(value): 与えられた値で解決されるPromiseを返します。
  • Promise.reject(reason): 与えられた理由で拒否されるPromiseを返します。
  • Promise.all(iterable): すべてのPromiseが解決されると解決されるPromiseを返します。
  • Promise.race(iterable): 最初のPromiseが解決または拒否されると解決または拒否されるPromiseを返します。

インスタンスプロパティとその利用

Promiseインスタンスには、特定のプロパティは公開されていません。

しかし、内部的には状態や値を持っています。

これらの内部プロパティは、Promiseの動作を理解するうえで重要です。

インスタンスメソッドとその利用

Promiseインスタンスは、以下のメソッドを持っています。

  • .then(onFulfilled, onRejected)
    Promiseが解決されたときや拒否されたときに呼び出されるコールバック関数を登録します。
  • .catch(onRejected)
    Promiseが拒否されたときに呼び出されるコールバック関数を登録します。.then(null, onRejected)と同等です。
  • .finally(onFinally)
    Promiseが解決または拒否された後に呼び出されるコールバック関数を登録します。

Promise.allとPromise.race – 並行処理の深堀り

こちらでは、複数のPromiseを効果的に扱うためのPromise.allPromise.raceについて、その動作原理や使用例を詳しく解説していきます。

  • Promise.allの使い方とその効果
  • Promise.raceの使い方とその効果

Promise.allの使い方とその効果

Promise.allは、複数のPromiseをひとつの配列として受け取り、Promiseが正常に解決された場合にのみ、新しいPromiseを解決するもの。

これは、複数の非同期処理がすべて完了するのを待つ場面で非常に役立ちます。

const promise1 = Promise.resolve('成功1');
const promise2 = Promise.resolve('成功2');

Promise.all([promise1, promise2]).then((values) => {
  console.log(values); // ['成功1', '成功2']
});

ただし、もし配列内のいずれかのPromiseが拒否されると、Promise.all自体もすぐに拒否されます。

Promise.raceの使い方とその効果

Promise.raceは、複数のPromiseのうち最初に解決または拒否されたPromiseの結果/理由に基づいて、新しいPromiseを解決または拒否するもの。

これは、複数の非同期処理の中で最初に完了するものを知りたい場合などに役立ちます。

const promise1 = new Promise((resolve) => {
  setTimeout(resolve, 500, '一つ目');
});
const promise2 = new Promise((resolve) => {
  setTimeout(resolve, 100, '二つ目');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value); // '二つ目'
});

この例では、promise2が最初に解決されるため、その結果が出力されます。

Promiseの応用事例コード – ひと通りの例を見てみよう

こちらではPromiseを使用した具体例をご覧いただきます。

  • 基本的な使用例
  • さまざまな状況への対応例
  • 高度な使用例

基本的な使用例

Promiseは、非同期処理の結果を表現するための強力なツールです。

例えば、APIからのデータ取得や、タイマーを使った遅延処理など、さまざまな場面で活用できます。

さまざまな状況への対応例

エラーハンドリングを含む、より複雑な非同期処理のシナリオも、Promiseを使って簡潔に表現できます。

例えば、リトライロジックや、タイムアウトの実装など、高度な非同期処理のパターンもPromiseで実装可能です。

高度な使用例

Promiseチェーンを利用することで、複数の非同期処理を順番に実行したり、並行して実行したりできます。

また、async/await構文を使うことで、非同期処理を同期的に書くことも可能です。

async/awaitを使ったPromise管理

async/awaitについてのPromise管理方法を見ていきましょう。

async/awaitはJavaScriptにおいてとても重要です。

  • asyncの理解と利用
  • awaitの理解と利用

asyncの理解と利用

asyncキーワードは、関数を非同期関数として宣言するもの。

asyncキーワードがついた関数は、必ずPromiseを返すようになります。

これにより、非同期処理をより直感的に書けるのです。

awaitの理解と利用

awaitキーワードは、非同期関数内でのみ使用できます。

awaitは、Promiseの解決を待ってから次の行を実行するという意味です。

非同期処理を同期的に書くことができ、コードの可読性が向上します。

まとめ

当記事では、JavascriptのPromiseについて学習してきました。

  • Promiseは、JavaScriptにおける非同期処理の核心的な部分
  • 正確な理解と適切な利用により、効率的でバグの少ないコードを書ける

当記事を通じて、Promiseの基本から高度なテクニックまでを学びました。

しかし、常に新しいパターンやベストプラクティスが出てくるため、継続的な学習と実践が必要です。

タイトルとURLをコピーしました