一部記事にはアフィリエイト広告が含まれています。

初心者エンジニア、JavaScriptの「非同期処理」と「API」をゼロから学ぶ

APIと非同期処理について初心者向けに解説していく。
APIと非同期処理をまとめて学ぶことで、実践で使える知識が身につく。

APIってなにもの?

API(Application Programming Interface)とは、アプリ同士がデータをやり取りするための窓口

✔️ 外部サービスが提供するAPI

外部サービスが提供するデータを、APIを利用することで取得できる。

例)天気予報アプリ
1. 外部の気象情報サービスから、APIを利用して天気データを取得
( 気象情報サービスは、天気データを提供するAPIを用意している )
2. 取得した天気データを画面に表示

✔️ 自分で作るAPI

APIを利用して、フロントエンド(JavaScript)からデータベースを操作できる。
フロントエンドはAPIを通じてデータの「取得・追加・更新・削除」をリクエストし、バックエンドが実際のデータベース操作を行う。

例)todoリストアプリ
1. ユーザーが画面上でtodoタスクを追加
2. フロントエンド(JavaScript)がAPIを使ってタスクデータを送信
3. バックエンド(PHPなど)が受け取ったデータを元に、SQLでデータベースにタスクを追加

まずは「外部サービスが提供するAPI」をイメージして、次の章に進んでほしい。

APIでデータを「取得」する方法

fetch関数を用いて、APIにてURLを通じてデータを取得できる。
→ Webサイトにアクセスするときと同じように、JSON形式のテキストデータで記述された、HTTPレスポンス(レスポンスオブジェクト)が返ってくる

fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then(response => response.json()) // JSONテキストをJavaScriptオブジェクトに変換
  .then(data => console.log("取得したデータ:", data)) // データを表示
  .catch(error => console.log("エラー:", error)); // エラー処理

✔️ fetch関数の流れ

正常バージョン

  1. 引数に設定したURLにアクセスし、レスポンスオブジェクトを返す
  2. レスポンスオブジェクトが、then()メソッドのresponseに渡され、response.json()を実行
  3. レスポンスオブジェクトのデータ部分だけを取り出し、JavaScriptオブジェクトに変換
  4. データ部分がthen()メソッドのdataに渡され、console.log("取得したデータ:", data)を実行

エラーバージョン(例)

  1. 間違ったURLの記載により、fetchが失敗
  2. fetch() はエラーを返す
  3. catch()メソッドのerrorに渡され、console.log("エラー:", error)を実行

✔️ HTTPレスポンスの正体

// 下記コードにて確認可能

fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(response => console.log("HTTPレスポンス:", response))

HTTPレスポンスは「データ本体」と「取得状況・情報」をまとめたオブジェクトである。

// レスポンスオブジェクトの中身(正常バージョン)

Response {
  type: "cors", // CORSリクエスト(他のドメインからのリクエスト)
  url: "https://jsonplaceholder.typicode.com/posts/1", // レスポンス元のURL
  status: 200, // データ取得の成功・失敗を示す(200なら成功、404ならデータなし)
  ok: true, // true(成功)または false(エラー)
  headers: Headers, // ヘッダー情報(データの種類やサーバー情報など)
  body: ReadableStream // 実際に欲しいJSONデータ
}
// レスポンスオブジェクトの中身(エラーバージョン)

Response {
  status: 404,
  ok: false,
  body: ReadableStream
}

ReadableStream:

body(データ本体)は、ReadableStream という形式で返ってくるので、そのままでは使えない。
→ 以下のメソッドで適切な形式に変換する必要がある

メソッド変換後の形式使う場面
response.json()JSON → JSオブジェクトAPIのデータ取得
response.text()プレーンテキスト(文字列)テキストデータの取得
response.blob()画像やPDFなどバイナリデータ画像・ファイルを扱う
response.arrayBuffer()バイナリデータ(ArrayBuffer)高度なデータ処理

✔️ JASON形式とは?

・ データをやり取りするための軽量なフォーマット(主にAPIで使用)
・ JavaScriptのオブジェクトに似た書き方の「文字列」
・ テキストデータなので、プログラミング言語に関係なく使える
・JavaScriptで使うためにはオブジェクトに変換する必要がある

// JASON形式のデータ

{
  "name": "Alice",
  "age": 25,
  "isStudent": false
}

「同期処理」と「非同期処理」を超わかりやすく解説

JavaScriptの関数には「同期処理」と「非同期処理」の2種類がある。

同期処理:タスクAが完了したら、タスクBを行う
     → タスクAは待ってもらえる

例:同期処理の例

console.log("A");
console.log("B");
console.log("C");

// A → B → C の順で出力(上から順番に実行)

非同期処理:処理に時間がかかるタスクAの完了を待たずに、タスクBを行う
      → タスクAは待ってもらえない

メリット:タスクAに時間がかかる場合、別の処理(タスクB)を実行でき、ユーザーを待たせない
デメリット:タスクB内で、タスクAで取得したデータを活用する場合、エラーが発生する

例1:setTimeout関数

console.log("A");

setTimeout(() => {
  console.log("B");
}, 1000); // 1秒後に実行される

console.log("C");

// A → C →(1秒後)B の順で出力
例2:APIによりデータ取得

console.log("データを取得開始");

fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then(response => response.json())
  .then(data => console.log("取得したデータ:", data))
  .catch(error => console.error("エラー:", error));

console.log("次の処理");


// 「データを取得開始」→「次の処理」→(データ取得完了後)「取得したデータ: {...}」

つまり、console.log同期関数setTimeout, fetch非同期関数である。

非同期処理の完了を待つ2つの方法

非同期処理だけど次のタスクに待ってもらいたい → 方法は2つ
例)APIによるデータ取得完了後に、画面に表示させる

方法①:Promise

fetch()Promise を返す関数のため、自分で定義する必要がない

fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then(response => response.json()) // JSONテキストをJavaScriptオブジェクトに変換
  .then(data => console.log("取得したデータ:", data)) // データを表示
  .catch(error => console.log("エラー:", error)); // エラー処理

手順(成功パターン)

  1. fetch(“URL”) を実行し、サーバーからデータを取得(ここは非同期)
  2. then(response => response.json())
    • サーバーのレスポンス(response)を受け取る
    • .json() を使ってデータを JSON 形式に変換
    • 変換が終わったら、次の then() にデータを渡す
  3. then(data => console.log(data))
    • JSON に変換したデータ(data)を受け取る
    • 画面に console.log() で表示
  4. エラーがないので catch() は実行されない

手順(失敗パターン)

  1. fetch("URL") を実行
  2. ネットワークエラーなどでデータを取得できなかった場合
    .then(response => response.json()) に行く前に catch() に飛ぶ
  3. catch(error => console.log("エラー:", error)) が実行される
    エラーの詳細(error)を console.log() で表示

自分でPromiseを定義する場合

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = true; // trueなら成功、falseなら失敗
    if (success) {
      resolve("成功しました!"); // 成功時
    } else {
      reject("失敗しました!"); // 失敗時
    }
  }, 2000);
});

// 実行後の流れ
myPromise
  .then(result => {
    console.log(result); // resolveの結果がここに入る
  })
  .catch(error => {
    console.log(error); // rejectの結果がここに入る
  });

1. new Promise() で Promise を作る
 ここで「成功するか」「失敗するか」を決める

2. resolve() を呼ぶと then() が実行される
 then() の中の関数の引数に resolve() の値が渡り、実行される

3. reject() を呼ぶと catch() が実行される
 catch() の中の関数の引数に reject() の値が渡り、実行される

✔️ .then().catch() 構文って?

Promise(非同期処理)専用
fetch() のような Promise を返す処理 に使う

方法②:async/await

async function fetchData() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
    const data = await response.json();
    console.log("取得したデータ:", data);
  } catch (error) {
    console.log("エラー:", error);
  }
}

fetchData();

fetch() でデータを取得する(await で完了を待つ
response.json() で JSON に変換(これも await で待つ)
console.log(data) でデータを表示
try ブロック内でエラーが発生したら、console.log("エラー:", error)を実行

try...catch 構文って?

try...catch「同期処理」でも「非同期処理」でもエラーをキャッチできる
async/await を使う場合に特に便利
.then().catch() はPromise(非同期処理)専用

try {
  // ここにエラーが出るかもしれない処理を書く
} catch (error) {
  // エラーが発生したときの処理
}

コメント