【JS応用|豆知識】Promise.resolveで非同期処理をスマートに統一しよう

1. 導入:なぜPromise.resolveが重要なのか

フロントエンド開発では、関数が「同期的に値を返す場合」と「非同期にPromiseを返す場合」の両方に対応しなければならない場面が頻繁にあります。もしこれらを別々に処理しようとすると、コードの分岐が増え、複雑で読みにくいものになってしまいます。Promise.resolve()を使うと、どんな値でも強制的にPromiseオブジェクトへ変換できるため、処理のフローを統一し、堅牢なコードを書くことが可能になります。

2. 基礎知識:Promise.resolveとは

Promise.resolveは、引数として渡された値を「解決済み(fulfilled)のPromise」として返却する静的メソッドです。もし引数が既にPromiseであればそのまま返し、それ以外の値(数値、文字列、オブジェクトなど)であれば、その値を解決結果とする新しいPromiseを作成します。この仕組みにより、呼び出し側は「相手がPromiseかどうかの確認」を意識することなく、常に .then() や async/await を使って結果を受け取ることができるようになります。

3. 実装/解決策:処理の共通化

例えば、キャッシュがある場合は即座に値を返し、ない場合はAPIを叩くといった関数を考えます。この際、戻り値をPromise.resolveでラップすることで、呼び出し側は常にawaitで値を受け取れるようになります。これにより、条件分岐による戻り値の型の揺れを解消できます。

4. サンプルプログラム

以下のコードは、キャッシュの有無に関わらず、常に非同期処理として振る舞わせる例です。

// キャッシュデータ(仮)
const cache = { name: "豆知識太郎" };

/
  • ユーザー情報を取得する関数
  • 値がキャッシュにあれば即座に返し、なければPromiseを返す
/ function getUser(id) { if (id === 1) { // キャッシュがある場合は即座に値を返す // Promise.resolveで包むことで、常にPromiseとして扱えるようにする return Promise.resolve(cache); } else { // キャッシュがない場合はAPIから取得(Promiseを返す) return fetch(`/api/users/${id}`).then(res => res.json()); } } // 呼び出し側:常にawaitで統一して記述できる async function init() { try { const user = await getUser(1); console.log("取得成功:", user.name); } catch (err) { console.error("エラーが発生しました:", err); } } init();

5. 応用・注意点:現場で役立つヒント

Promise.resolveは便利な反面、注意すべき点もあります。それは「マイクロタスク」としての実行です。Promise.resolveで解決した内容は、現在の同期的な処理がすべて完了した後の「マイクロタスクキュー」で実行されます。そのため、同期的に値を返しているつもりでも、実際には呼び出し側の次の行の実行順序に影響を与えることがあります。

また、失敗する可能性がある処理に対しては、Promise.resolveの対となる Promise.reject() を適切に使い分けることが大切です。これらを活用することで、現場のコードベースにおける非同期処理の制御が格段にクリーンになります。ぜひプロジェクトの共通関数などで活用してみてください。

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