JavaScriptの非同期処理 Promiseからasync/awaitまでの使い方

JavaScriptで非同期処理を書くのは、ユーザー体験を快適にするためにとても大切です。
とはいえ、昔ながらの書き方ではコードが複雑になりやすく、「コールバック地獄」と呼ばれる問題もありました。
そんな悩みを解決するのが Promise です。

この記事では、Promiseの基本から、それをもっとシンプルに書ける async/await の使い方、そして実践的な例まで順番に紹介します。

Promiseの基本

Promiseは「非同期処理の結果(成功か失敗か)」を表すオブジェクトです。
次の3つの状態を持っています。

  • pending (保留): 最初の状態。まだ結果が出ていない。
  • fulfilled (成功): 無事に処理が終わった。
  • rejected (失敗): エラーなどで処理が失敗した。

一度 fulfilled または rejected になると、その結果は変わりません。

基本の書き方

Promiseは .then()(成功時)、.catch()(失敗時)、.finally()(どちらの場合も最後に実行)をつなげて書きます。

function someAsyncTask() { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() > 0.5) { resolve("処理が成功しました"); } else { reject(new Error("処理が失敗しました")); } }, 1000); });}someAsyncTask() .then(successMessage => { console.log(successMessage); }) .catch(error => { console.error(error.message); }) .finally(() => { console.log("処理が終わりました"); });
JavaScript

async/awaitでさらに書きやすく

async/await は、Promiseをもっと自然な形で書けるようにした構文です。
まるで同期処理のように書けるので、とても読みやすくなります。

  • async: 関数の前につけると、その関数は必ずPromiseを返します。
  • await: async関数の中で使い、Promiseの結果が返ってくるまで待ちます。エラー処理には try...catch を使います。
async function executeTask() { try { const result = await someAsyncTask(); console.log(result); } catch (error) { console.error(error.message); } finally { console.log("処理が終わりました"); }}executeTask();
JavaScript

このように書くと、ネストが深くならず、とても見通しがよくなります。

実践例:アニメーションのタイミングをコントロール

async/await は、ステップが多い処理やアニメーションの制御にも便利です。
例えば、setTimeout をPromise化した関数を作ると、アニメーションの順番をわかりやすく書けます。

HTMLとCSS

<div id="box"></div>
HTML
#box { width: 100px; height: 100px; background-color: tomato; opacity: 0; transform: translateX(-50px); transition: opacity 0.5s, transform 0.5s;}#box.show { opacity: 1; transform: translateX(0);}
CSS

JavaScript

function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms));}async function animateBox() { const box = document.getElementById('box'); await delay(1000); box.classList.add('show'); await delay(2000); box.classList.remove('show');}animateBox();
JavaScript

このように await delay() を挟むだけで、処理のタイミングを簡単に調整できます。

複数のPromiseをまとめて扱う

複数の非同期処理を同時に実行したい場合は、Promise.allPromise.race が便利です。

  • Promise.all(promises)
    すべてのPromiseが成功したら結果を配列で返します。ひとつでも失敗するとそこでエラーになります。
  • Promise.race(promises)
    いずれかのPromiseが最初に終わった時点で、その結果を返します。タイムアウト処理などに向いています。

まとめ

Promiseは、JavaScriptの非同期処理を扱うための基本的な仕組みです。
さらに async/await を使うと、コードがすっきりして読みやすくなり、書くのも楽になります。
これらを上手に使いこなして、快適で保守しやすいコードを書いていきましょう。

read next