ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
同期と非同期の違い
| 観点 | 同期処理 | 非同期処理 |
|---|---|---|
| 実行順 | 上から順に実行、終わるまで次に進まない | 処理を予約してすぐ次に進む |
| UI ブロック | 長いと固まる | 固まらない |
| 例 | for ループ、JSON.parse | fetch、setTimeout、fs.readFile |
| 結果取得 | 直接 return | コールバック / Promise / await |
イベントループの基本
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 出力順: 1 → 4 → 3 → 2
// 理由:
// 1, 4 は同期 (Call Stack で即実行)
// 3 は microtask (Promise) → Call Stack 空になった瞬間
// 2 は macrotask (Timer) → microtask 後
優先度: 同期コード > microtask (Promise / queueMicrotask) > macrotask (setTimeout / setInterval / I/O)。
コールバック地獄
// ❌ Callback Hell
getUser(userId, (err, user) => {
if (err) return handleError(err);
getOrders(user.id, (err, orders) => {
if (err) return handleError(err);
getItems(orders[0].id, (err, items) => {
if (err) return handleError(err);
getPrice(items[0].id, (err, price) => {
if (err) return handleError(err);
// 深くなりすぎ
console.log(price);
});
});
});
});
Promise: 非同期処理の合成
// 基本: Promise の作成
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve(42), 1000);
});
// 消費: then / catch / finally
p.then(value => console.log(value)) // 42
.catch(err => console.error(err))
.finally(() => console.log('done'));
// チェーンで非同期を直列に
fetch('/api/user')
.then(res => res.json())
.then(user => fetch(`/api/orders/${user.id}`))
.then(res => res.json())
.then(orders => console.log(orders))
.catch(err => console.error(err));
async/await: Promise の糖衣構文
// ✅ async/await で同期風に書ける
async function loadUserData(userId) {
try {
const user = await getUser(userId);
const orders = await getOrders(user.id);
const items = await getItems(orders[0].id);
const price = await getPrice(items[0].id);
return price;
} catch (err) {
console.error(err);
}
}
// 呼び出し側
loadUserData(123).then(price => console.log(price));
// または別の async 関数内で
const price = await loadUserData(123);
並列待ち: Promise.all / allSettled / race / any
// Promise.all: 全部成功なら配列、1つでも失敗で reject
const [users, orders, items] = await Promise.all([
fetch('/users').then(r => r.json()),
fetch('/orders').then(r => r.json()),
fetch('/items').then(r => r.json()),
]);
// Promise.allSettled: 全部の結果を待つ (失敗もOK)
const results = await Promise.allSettled([
fetch('/a'), fetch('/b'), fetch('/c'),
]);
results.forEach(r => {
if (r.status === 'fulfilled') console.log(r.value);
else console.error(r.reason);
});
// Promise.race: 最初に決着した1つ
const winner = await Promise.race([
fetch('/slow'),
new Promise((_, rej) => setTimeout(() => rej('timeout'), 5000)),
]);
// Promise.any: 最初に成功した1つ (ES2021)
const fastest = await Promise.any([
fetch('//cdn1/data.json'),
fetch('//cdn2/data.json'),
fetch('//cdn3/data.json'),
]);
逐次 vs 並列の落とし穴
// ❌ 直列実行 (合計 3 秒)
const a = await fetchA(); // 1秒
const b = await fetchB(); // 1秒
const c = await fetchC(); // 1秒
// ✅ 並列実行 (合計 1 秒)
const [a, b, c] = await Promise.all([
fetchA(), fetchB(), fetchC(),
]);
// ❌ map + await でも直列にはならない
const results = await Promise.all(
urls.map(url => fetch(url))
);
setTimeout / setInterval
// 1 秒後に実行
const timerId = setTimeout(() => {
console.log('1 second later');
}, 1000);
// キャンセル
clearTimeout(timerId);
// 1 秒ごとに繰り返し
const intervalId = setInterval(() => {
console.log('tick');
}, 1000);
// 停止
clearInterval(intervalId);
// 注意: setTimeout(fn, 0) でも即時実行されない
// 最低でも 4ms (HTML5 仕様で網入れあり) かかる
microtask: process.nextTick / queueMicrotask
// queueMicrotask (標準。ブラウザ + Node)
queueMicrotask(() => {
console.log('microtask');
});
// process.nextTick (Node のみ。microtask より更に優先)
process.nextTick(() => {
console.log('nextTick');
});
// 実行優先度
// 同期 > process.nextTick > microtask (Promise) > macrotask (setTimeout)
エラーハンドリング
// async 関数の中は try/catch で受ける
async function loadData() {
try {
const data = await fetch('/api/data').then(r => r.json());
return data;
} catch (err) {
console.error('Failed:', err);
throw err; // 上に伝播
}
}
// Promise チェーンは .catch で
fetch('/api/data')
.then(r => r.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// 未捕捉 Promise を補足
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled:', reason);
});
// ブラウザ
window.addEventListener('unhandledrejection', (e) => {
console.error('Unhandled:', e.reason);
});
真の並列: Worker Threads / Web Workers
JavaScript はシングルスレッドだが、別スレッドで CPU 集約処理を回すことができます:
// Node.js Worker Threads
import { Worker } from 'node:worker_threads';
const worker = new Worker('./heavy.js');
worker.on('message', (result) => console.log(result));
worker.postMessage({ task: 'compute', data: largeArray });
// ブラウザ Web Workers
const worker = new Worker('worker.js');
worker.onmessage = (e) => console.log(e.data);
worker.postMessage({ task: 'compute' });
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data);
self.postMessage(result);
};
ベストプラクティス
- async/await を基本。Promise チェーンより読みやすい
- 並列できるものは Promise.all でまとめる
- エラーは必ず try/catch または .catch() で受ける
- 長い CPU 処理はWorker に逃がし、UI を固まらせない
- process.exit() は最終手段。awaitが終わる前に切ると非同期処理が失われる
- テストでは jest.useFakeTimers() / vi.useFakeTimers() で時間を操る
FAQ
Q: forEach の中で await が効かないのはなぜ?
A: forEach は async 関数を受け取っても待たない設計。for...of または Promise.all + map を使います。
Q: コールバック関数を Promise 化したい
A: Node なら util.promisify(fn)。自前なら new Promise((resolve, reject) => fn(args, (err, val) => err ? reject(err) : resolve(val)))。
Q: await を忘れたら何が起きる?
A: その関数はPromise オブジェクトをそのまま返します。中身を使うとバグります。TypeScript なら型エラーで気付けます。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?