async / awaitについて、再確認(超初心者向け)
はじめに
カレーを作るとき、ご飯を炊く作業と野菜を切る作業は同時に進められますが、ご飯をお皿によそうのは、ご飯が炊き上がるまで待たなければできません。このような状況をコンピューターの世界で考えると、ご飯を炊きながら野菜を切るのは「非同期処理」、ご飯が炊き上がるまで待つのは「同期処理」と呼ばれます。そして、この同期・非同期の動作をプログラム上で指示するために使われるのが、async / await という構文です。
この記事では、この async / await をわかりやすく解説します。
async / await は、プログラムの中で「一度にすべて処理せず、完了するのを待ちながら進める」仕組みを簡単に書けるようにするための方法です。たとえば、インターネットから情報を取得する場合、データが返ってくるまで時間がかかることがあります。その間、プログラムを停止させるのではなく、他の作業を並行して進めることができるのです。
ここでは、JavaScript での async
/ await
の使い方や注意するポイントを説明します。
基本的な使い方
async
とは?
async
を関数の前に付けることで、その関数は非同期であることを示します。
関数(プログラムのまとまり)の前に async
を付けると、「この関数の中には、終わるのを待たなければいけない作業があるかも」とプログラムに教えることができます。
async
の例
async function getMessage() {
return "こんにちは!";
}
相手に挨拶をして、返事を画面に表示させるアプリを作ります。この関数は「こんにちは!」と返すのですが、返事がすぐに返ってこない場合を想定して(すぐに挨拶してくれない人もいるので)非同期として扱っています。
await
とは?
await
を使うと、「この作業が終わるのを待つよ」という指示が出せます。await
は必ずasync
関数の中で使用する必要があります。
await
の例
async function showMessage() {
const message = await getMessage(); // getMessageが終わるのを待つ
console.log(message); // 結果を表示する
}
showMessage();
// 出力: こんにちは!
このプログラムでは、まず getMessage() が終了するのを待ち、その結果を message に代入します。その後、その結果を画面に表示します。
これは文字を返すだけの簡単な例ですが、たとえば、メッセージを取って来るためにネットワークに問い合わせを行う場合、返事が届くまでに数秒かかることがあります。await を付けると、返事が届くのを待ってから値を受け取ることができますが、await を付けない場合は、メッセージを受け取る前にテキストではない値が画面に出力されてしまいます。
エラーが起きたらどうする?
プログラムを実行するとにエラーが起きることもあります。たとえば、インターネットが繋がらないときです。その場合は try
(やってみる)と catch
(失敗したらこうする)を使います。
-
fetch()
関数について
fetch は、例えばインターネットを経由して相手からのメッセージを取得するときに使います。
jsonplaceholder.typicode.com はメッセージの代わりにレスポンスを返すテストサイトです。
エラーを拾い上げる例
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.error("返事を受け取れませんでした:", error);
}
}
fetchData();
このように書くと、エラーでアプリが止まることを防ぐことができます。
async
/ await
を使うときの注意点
JavaScript で非同期処理を使うとき、async
は非常に便利です。でも、正しく使わないと、予想外の動きをしてしまうことがあります。
await
を使うと順番に動いてくれます。ただ、何にでも await
を使えば良いわけではなく、使い方は以下のように考えましょう。
方法 | よい | わるい |
---|---|---|
awaitを使う | 順番をきっちり守って動く | 一個ずつ動くから遅く感じることがある |
awaitを使わない | いろんなことを一気にできる | 順番がバラバラになる |
await
を使うと RPGのようなゲームでキャラクターが順番に行動するみたいなイメージです。
一方 await
を使わないのは、フォートナイトのようにみんなが同時に動いてワイワイしている感じです。でも、順番を決められないから困ることもありますよね。
await
をつけないとどうなる?
await
をつけないで async
関数を呼び出すと、関数の中の処理が「バックグラウンドで実行」されます。そのため、プログラムの処理順序が変わることがあります。
例えば、次のコードを見てみましょう。
- メイン関数(
main()
)が非同期でサブ関数(fetchData()
)を実行します。
// 非同期で、web読込を行う関数(読み込み、JSON化する)
const fetchData = async (id) => {
console.log("データを取得中..."); // タイトルを表示
const response = await fetch("https://jsonplaceholder.typicode.com/posts/" + id);
const data = await response.json();
console.log(data);
console.log("データを取得完了");
return;
};
// 非同期で実行するメイン関数
const main = async () => {
console.log("[main 開始]"); // メイン関数の開始表示
// データを取得
fetchData(1);
// データを取得
fetchData(2);
console.log("[main 終了]"); // メイン関数の終了表示
};
// mainを実行。呼び先で非同期にサブ関数を呼ぶ。
main();
このコードの実行結果はたまたま次のようになりました。id が 2 -> 1 の順になっています。これは、fetchData が非同期に実行され、相手のサーバがレスポンスを返す順に処理が終わるので、順序が保証されないためです。
% node sample_load_async.js
[main 開始]
データを取得中...
データを取得中...
[main 終了]
{
userId: 1,
id: 2,
title: 'qui est esse',
body: 'est rerum tempore vitae\n' +
'sequi sint nihil reprehenderit dolor beatae ea dolores neque\n' +
'fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\n' +
'qui aperiam non debitis possimus qui neque nisi nulla'
}
データを取得完了
{
userId: 1,
id: 1,
title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
body: 'quia et suscipit\n' +
'suscipit recusandae consequuntur expedita et cum\n' +
'reprehenderit molestiae ut ut quas totam\n' +
'nostrum rerum est autem sunt rem eveniet architecto'
}
データを取得完了
fetchData()
が始まるとすぐに “[main 終了]” が表示されます。これは、await
をつけていないため、fetchData
の実行を待たずに次の行に進んでしまうからです。
更に、id が 2 -> 1 の順になっています。id 順に表示させたい場合、この順番では困りますよね。このように、await
を忘れると処理の順序が予想外になり、問題を引き起こすことがあります。
どうすればいい?
await
をつける。
次のコードを見てみましょう。先ほどと違うのは fetchData()
を呼ぶときに await
をつけているだけです。
// 非同期で、web読込を行う関数(読み込み、JSON化する)
const fetchData = async (id) => {
console.log("データを取得中..."); // タイトルを表示
const response = await fetch("https://jsonplaceholder.typicode.com/posts/" + id);
const data = await response.json();
console.log(data);
console.log("データを取得完了");
return;
};
// 非同期で実行するメイン関数
const main = async () => {
console.log("[main 開始]"); // メイン関数の開始表示
// データを取得
await fetchData(1);
// データを取得
await fetchData(2);
console.log("[main 終了]"); // メイン関数の終了表示
};
// mainを実行。呼び先で非同期にサブ関数を呼ぶ。
main();
このコードの実行結果は次のようになります(%はプロンプトです):
% node sample_load_await.js
[main 開始]
データを取得中...
{
userId: 1,
id: 1,
title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
body: 'quia et suscipit\n' +
'suscipit recusandae consequuntur expedita et cum\n' +
'reprehenderit molestiae ut ut quas totam\n' +
'nostrum rerum est autem sunt rem eveniet architecto'
}
データを取得完了
データを取得中...
{
userId: 1,
id: 2,
title: 'qui est esse',
body: 'est rerum tempore vitae\n' +
'sequi sint nihil reprehenderit dolor beatae ea dolores neque\n' +
'fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\n' +
'qui aperiam non debitis possimus qui neque nisi nulla'
}
データを取得完了
[main 終了]
今度は fetchData()
が始まると、 “データを取得中…"、“データを取得完了” と表示され、最後に “[main 終了]” が表示されます。これは、await
をつけているため、fetchData
の実行が終わるのを待っているからです。
何度実行しても期待通り id 順に表示されてますよね。一方で、順番に処理をしているので、時間がかかってしまいます。
まとめ
async
関数を使うときは、処理を同期する場合、await
を忘れないようにしましょう。await
を忘れると処理順が入れ替わることがあります。用途に応じて使い分けるようにしましょう。
このように、async
/ await
構文を使えばある程度、非同期、同期を組み合わせた処理を簡潔に書けるようになります。
しかし、関数が増えるとどうでしょう。また、 promise.all や promise.race を駆使するような async
/ await
処理になると、関数の依存関係が複雑になり、かなり難しいコードになります。
そこでGraphAIの出番になります。
GraphAIは宣言型のプログラミングスタイルで非同期処理を簡潔に記述することができます。
GraphAIのイメージ。
関連ページ
- GraphAI Contribution Fes 2025 開催のお知らせ
- async / awaitについて、再確認(超初心者向け)
- 私の寿命、あと何年?
- HtmlRAG: HTML is Better Than Plain Text for Modeling Retrieved Knowledge in RAG Systemsの紹介
- Magentic-One: A Generalist Multi-Agent System for Solving Complex Tasksの紹介
- 書評:LangChainとLangGraphによるRAG・AIエージェント[実践]入門 (エンジニア選書)
- SS推薦の図書
- Singularity Societyに入るには?
- 話題のネコ型ロボット「ミーア」!パワーアップします!
- 「世界モデルを持たないLLM」にとって難しい質問のリスト
- Raycastの機能拡張をカスタマイズ(テンプレート解説)
- RaycastJapan Meetup 第0回 イベントレポート
- Raycastのイベント発表資料
- Macの生産性を10倍上げるRaycastのイベント開催!!
- 「蔦屋家電+」ミーアの展示期間を延長しました!
- 安野たかひろ × 中島聡 緊急対談 書き起こし
- 蔦屋家電+でミーアたちに合う
- 安野たかひろ × 中島聡 緊急対談
- 蔦屋家電+とTi B SHOPでおしゃべり型ロボット「ミーア」に会いに行こう🐾
- W&Bミートアップ#13in東京 Stability AIとTuringからモデルサービングの最新手法を学ぶMeetup
- Turing CTOが語る自動運転2.0 生成AIで実現する次世代自律運転
- サンノゼで開かれたVisionProハッカソンに参加しました!
- おしゃべり猫型ロボット「ミーア」を開発
- コストコを超えるイノベーション!高品質・サプライズ価格なECの立ち上げ
- 空間ジェスチャーアプリを作る
- Turing Semiconductor/AI Day潜入レポ
- アーバンデータチャレンジ2023にてW受賞しました
- visionOSアプリ、Teegardenの開発物語
- エンジニア未経験のPMがChatGPTを使って簡単なプログラミングだけでプロダクトを作った話
- 新しい挑戦を躊躇する心理:優先順位の真実
- 時を超える知の投資:良書と大学教育の意義
- 動画生成AI SORAの革新とサム・アルトマンのビジョン
- イノベーションを起こしやすい組織について
- サッカー選手になりたいが、サッカーボールを蹴ったことがない人の話
- 2024年、国産クラウドに期待
- 仕事と焼肉、意外な共通点とは?
- 業界に激震!!Llama2オープン化がいかにすごいかを解説。
- OpenAIによる今回のアップデートがなぜ私たち開発者たちの間で「神アップデート」と呼ばれているか解説!!
- 統計的自然言語処理によりおぼろげながら浮かんできた思考の仕組みと教育の未来
- アプリ開発の常識を覆す? GPT-4の凄さに魅了された体験談
- あなたの NFT がゴミになるかもよ?
- GPT3の本質を理解し、ChatGPTを使いこなす為に知っておきたい事!!
- 今世紀のベストペーパー
- 「Web3がもたらす未来を考える」中島聡×塚田学対談
- これが未来の生活スタイル。遊牧民のように旅をしながら暮らす理想のノマドライフの提案。
- あなたのNFTは大丈夫?!某NFTが存在するのか確認してみました。
- 元米マイクロソフトのソフトウェアエンジニアが教える「エンジニアになりたいなら知っておいた方がいいコト!」
- 「フルオンチェーンでないNFTの怖さ」が現実に!〜フルオンチェーンNFTを可能にする技術
- 知らないと恐ろしい事に!AM/PM表記のなぞ?!
- DAOに対する「株式会社に代わる新しい仕組み」や「参加者全員が成功の果実を共有できる」という認識は間違いです。DAOの本質とは?
- スマートコントラクトが人々の行動を変え世界を変える!!
- フルブロックチェーンのスマートコントラクトは世の中に価値を提供し続ける!
- ビットコインこそ「究極のDAO」
- Pride Squiggle で画像をオンチェーンでダイナミックに生成するために使ったテクニック
- Netscapeからシェアを奪い取ったInternet Explorerが、終焉してしまった理由
- ソフトウェア・アーキテクチャの面からWeb2.0とWeb3の違いを分かり易く解説
- Web3の技術は素晴らしいがそれを生かすも殺すもエンジニア次第!
- AppleのWWDC22の基調講演で、最も私に刺さったのはCarPlay!!これが何を意味するのか?!
- Web3時代!NounsDAOの最大の発明はこれだ!
- 日本のシステムは最大のポンジースキームだった!?
- そして、すべてはソフトウェアになった
- パーソナル・ブランディング
- あなたの知らないWeb3/NFT/DAOの真実
- ハッカソン開会式のご挨拶「過去の戦争と比べて違うなと思うところ」
- NounsDAOをフォークした人にインタビューを受けました(翻訳)
- すでに解散したバンドのファンになった話
- 帝国化する企業と民主主義の末路
- 衰退していく日本のテレビ業界について語る
- Youtube のダークサイド
- 「理解できない」と言える強さ
- Oculus Go
- メタバース時代に掘り起こせそうな本屋さん
- 日本は少子高齢化・人口減少で新しい枠組みを作るのに良い実験場-<コモン>の領域を再建し人々の生活を安定させる
- Nintendo Switch とエクササイズ・バイク
- こんなダメな日本がかわるきっかけは「戦争か大災害しかない」噴火・地震・メタバースなど
- カルト・オンライン
- 中島聡×草場 壽一 「ソサエティを立ち上げた思い」
- 人工知能・機械学習の父
- 起業家と現実歪曲空間
- デマンド交通『おでかけ号』のタクシー予約/配車システムをDX化、高知・土佐清水で新登場
- 中島聡×SONY社内イベント
- メルカリ × 中島聡 ディスカッション イベントレポート
- 自動車業界の近未来
- 未来の社会のあり方
- SS推薦の動画
- 汎用人工知能・強いAIの開発にまつわる懸念点
- 未来のソフトウェアエンジニア教育を考える
- 財政出前講座 SIM2030
- Elon Musk の悩み
- Elon Musk のビジョン
- 自動運転社会のひとつの形
- Amazon Goに行ってみた
- 中島さん関連動画