なぜ処理が“止まったように見える”のか?
Webアプリを作っていて、次のようなことに心当たりはありませんか?
-
ボタンを押してもすぐに反応がない
-
データ取得後に画面更新がうまくいかない
-
処理の順番が想定と違って混乱する
これらの現象は、実は「非同期処理」という考え方と深く関係しています。
初めてプログラミングを学んだとき、多くの人が上から順に処理される「同期的な流れ」を前提に考えがちです。
でも、現実のプログラムではすぐに終わらない処理(例:通信や読み込み)がたくさんあります。
そうした処理を正しく扱わないと、画面が固まったり、処理の順番がズレたりしてしまうのです。
こうしたときに必要になるのが、「非同期処理」の知識です。
非同期とは?まずはイメージから理解しよう
非同期のイメージをつかむ「ラーメン屋の例」
-
お客さんがラーメンを注文します
-
店員は「作りますね」と伝えて、他のお客さんの注文を受けに行きます
-
ラーメンができたら店員がテーブルに持ってきます
これが非同期の処理です。
「作っている間、他のこともできる」という考え方ですね。
一方、ラーメンができるまでその場に立ち尽くして何もしない店員がいたら、それは同期処理のイメージです。
非同期処理が使われる場面
-
サーバーと通信してデータを取得するとき
-
ファイルや画像を読み込むとき
-
タイマーで一定時間待機したあとに処理するとき
-
重たい計算やフィルター処理を実行するとき
こういった処理は、すぐには終わらないため、非同期で扱う必要があります。
同期処理と非同期処理の違い
同期処理の特徴
-
処理の流れ:上から順に実行される
-
次の処理:前の処理が終わるまで止まる
-
結果の取得:その場ですぐ得られる
-
実行例
console.log("A");
console.log("B");
非同期処理の特徴
-
処理の流れ:完了を待たずに次へ進む
-
次の処理:裏で進行しつつ他の処理も進む
-
結果の取得:あとで受け取る(通知やコールバック)
-
実行例
fetch("data.json").then(res => console.log(res));
実際にコードで非同期処理を体感してみよう
JavaScriptで非同期処理を試す
1. setTimeoutによる非同期の例
console.log("処理1");
setTimeout(() => {
console.log("処理2(2秒後に実行)");
}, 2000);
console.log("処理3");
実行結果
-
処理1
-
処理3
-
処理2(2秒後)
2. Promiseを使って非同期結果を扱う
function getData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("データ取得完了");
}, 1000);
});
}
getData().then((result) => {
console.log(result);
});
3. async/awaitでスッキリ書く
async function main() {
const result = await getData();
console.log(result);
}
main();
Javaでも非同期処理はできる
ExecutorServiceとFutureを使った例
import java.util.concurrent.*;
public class AsyncExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
Thread.sleep(2000);
return "バックグラウンド処理完了";
});
System.out.println("メインスレッドは先に進みます");
String result = future.get(); // 結果が返るまで待機
System.out.println(result);
executor.shutdown();
}
}
よくあるつまずきポイント
1. コールバック地獄
-
ネストが深くなって読みにくい
-
解決策:Promiseやasync/awaitでフラットに書き換える
2. 非同期で変数がうまく扱えない
let result;
fetch("data.json")
.then(res => res.json())
.then(data => {
result = data;
});
console.log(result); // まだundefined
-
解決策:async/awaitで順序を保証する
Before / Afterで見比べてみよう
Before:同期処理で3秒間フリーズ
function heavyTask() {
const start = Date.now();
while (Date.now() - start < 3000) {} // フリーズ
console.log("完了");
}
heavyTask();
After:非同期でサクサク表示
function heavyTask() {
setTimeout(() => {
console.log("完了(非同期)");
}, 0);
}
heavyTask();
「非同期」を知ると、アプリはもっとスムーズになる
非同期処理の理解が広げる開発の世界
-
時間のかかる処理を止めずに裏で動かすのが非同期処理
-
JavaScriptでは setTimeout / Promise / async/await が基本
-
Javaでは ExecutorService / Future を使ってスレッドを操作
-
非同期を理解することでUIのフリーズや順序ミスを回避できる
【外部リンク】
【内部リンク】
JavaScriptでCORSエラーが出たときの原因と対処法を徹底解説
JavaScriptのAjax完全入門|fetchの使い方・CORSエラーの対処・非同期通信の基本を解説
JavaScriptでよく発生するエラー「ReferenceError」「SyntaxError」などの原因と対策を具体例付きで解説