KAKUTA TECH BLOG

Blog Article

async / awaitを使った非同期処理

はじめに

JavaScriptで非同期処理を書くとき、これまで .then() や .catch() を使ったPromiseチェーンに苦戦した方も多いのではないでしょうか。

この記事では、async / await の基本的な使い方から、よくあるエラー処理の書き方、そして try / catch を使った実践的なパターンまで、解説します。

そもそも「非同期処理」って?

JavaScriptは、基本的に上から順番に処理していきます。でも、時間がかかる処理 (たとえば、サーバーからデータを取ってくる処理やファイル処理など) は、すぐに終わらないことがありますよね。

こういう「すぐに終わらない処理」のことを非同期処理といいます。

同期処理の例(順番通りに実行される)
console.log('1: データを取得します');
console.log('2: データ取得完了');
console.log('3: 次の処理');

// 実行結果
1: データを取得します
2: データ取得完了
3: 次の処理
  • 上から順番に処理される
  • 1行目が終わる → 2行目 → 3行目
  • 時間がかかる処理でも、順番を待ってから次に進む
非同期処理
console.log('1: データを取得します');

setTimeout(() => {
  console.log('2: データ取得完了');
}, 2000);

console.log('3: 次の処理');

// 実行結果
1: データを取得します
3: 次の処理
2: データ取得完了  ← 2秒後に表示
  • setTimeout が非同期処理の例
  • JavaScriptは「時間がかかる処理」を待たずに次の行を実行する
  • 2秒後にコールバック関数が実行される

ここでは setTimeout を使って、2秒後に「2: データ取得完了」が出るようにしています。

このように、すぐに終わらない処理は、あとで実行される

→ これが「非同期処理」です。

asyncとawaitって何?

asyncとは、関数の前につけるキーワードで、「この関数の中では非同期処理が使えますよ!」とJavaScriptに教えるものです。

async function fetchData() {
  // 非同期処理が使える!
}

await とは、async 関数の中で使うキーワードで、「この処理が終わるのを待ってから次に進んでね」と指示します。

const data = await fetch("https://example.com/data.json");

async functionの戻り値はPromiseになる

async を関数の前につけると、その関数は必ず Promise を返す関数になります。JavaScript が自動的に、関数の戻り値を Promise に変換してくれる仕組みです。この仕組みのおかげで、非同期処理をより簡単で見やすく書けるようになります。

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

状態

英語名

意味

1. 待機中

pending

まだ結果が返ってきていない状態(処理中)

2. 成功

fulfilled

処理が成功して、値が返された状態

3. 失敗

rejected

処理が失敗して、エラーが返された状態

Promise は処理の結果に応じて、pending → fulfilled または rejected に状態が変化します。

処理が成功すると resolve() が呼び出され、Promise は fulfilled(成功)状態になります。その結果、then() メソッドに登録した処理が実行されます。

一方、処理が失敗すると reject() が呼び出され、Promise は rejected(失敗)状態になります。その結果、catch() メソッドに登録した処理が実行されます。

つまり、resolve() が呼ばれると then()、reject() が呼ばれると catch() につながると考えると理解しやすいです。


async function sayHello() {
  return "こんにちは!";
}

const result = sayHello();
console.log(result);

この関数を実行すると、下記のような出力結果が出ます。

Promise { <fulfilled>: "こんにちは!" }

つまり、async functionの戻り値は、必ずPromiseになります。

上記のreturn "こんにちは!"は、Promise.resolve("こんにちは!") と同じ意味になります。逆に、async functionが値をthrow した場合、その値をrejectします。

asyncとawaitがないとこのような記述になります。この記述では、ネストが多くて、わかりにくいです。

fetch("<https://example.com/data.json>")
  .then(response => response.json())
  .then(data => {
    console.log("データ取得:", data);
  });

次に async とawait を使ったコードです。

asyncとawaitを記述するとスッキリ書くことができます。他にも、コードが読みやすいというメリットもあります。非同期処理なのに、同期処理 (普通の順番)みたいに読めるので、バグが起きにくいです。

async function getData() {
  const response = await fetch("<https://example.com/data.json>");
  const data = await response.json();
  console.log("データ取得:", data);
}

getData();

まとめ

用語

意味

async

非同期関数を定義する(中でawaitが使える)

await

結果が返ってくるまで待つ

使いどころ

データ取得、ファイル読み込みなど時間がかかる処理