JavaScriptの非同期処理とは、あるタスクを実行している間に、他のタスクが別の処理を実行できる方式です。
例えば、データベースから値を取得するなどの通信を伴う処理は、通信状況によって時間がかかる可能性があります。
その場合、非同期処理を使うと、通信が完了するまで待つのではなく、他の処理を進めることができます。
今回はJavaScriptの非同期処理について、簡単で分かりやすいサンプルコードを用いて解説します!
非同期処理のサンプルコード
JavaScriptでは、非同期処理を実現するために、コールバック関数やPromise
やasync
/await
などの機能があります。
コールバック関数とは、ある関数に引数として渡されて、その関数の中で呼び出される関数です。Promise
とは、非同期処理の結果を表すオブジェクトで、「成功」や「失敗」などの状態や値を持ちます。async
/await
とは、Promise
をよりシンプルに書くための構文で、「async」キーワードで関数を定義し、「await」キーワードでPromise
の結果を待ちます。
![](https://minory.org/wp-content/uploads/2022/01/avater-150x150.png)
シンプルなサンプルコードで解説していきます!
コールバック関数
コールバック関数とは、ある関数に引数として渡されて、その関数の処理が終わったら呼び出される関数のことです。
非同期通信に使われる場合、コールバック関数は非同期処理の結果を受け取って、その後の処理を行います。
例えば、setTimeout
関数は非同期処理の代表的な関数で、指定した時間が経過したらコールバック関数を実行します。
1 2 3 4 |
// 2秒後に"Hello"と表示する setTimeout(function() { console.log("Hello"); }, 2000); |
上記のコードでは、2秒後に「Hello」と表示するコールバック関数をsetTimeout
関数に渡しています。
コールバック関数のサンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 非同期処理(1秒後にHello World!と表示する) function asyncFunc(callback) { setTimeout(() => { console.log("Hello World!"); callback(); // コールバック関数 }, 1000); } // 非同期処理(1秒後にGoodbye!と表示する) function asyncFunc2() { setTimeout(() => { console.log("Goodbye!"); }, 1000); } // 非同期処理を順番に実行する asyncFunc(asyncFunc2); // Hello World! -> Goodbye! |
コールバック関数は非同期処理の基本ですが、複雑な処理をする場合はネストが深くなったり、エラー処理が煩雑になったりする問題があります。
もっと詳しい解説はこちら。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Fpublic%2Farticle-ogp-background-412672c5f0600ab9a64263b751f1bc81.png?ixlib=rb-4.0.0&w=1200&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTk3MiZoPTM3OCZ0eHQ9JTVCSmF2YVNjcmlwdCU1RCUyMCVFOSU5RCU5RSVFNSU5MCU4QyVFNiU5QyU5RiVFNSU4NyVBNiVFNyU5MCU4NiVFMyU4MSVBRVByb21pc2UlMkMlMjBhc3luYyUyQyUyMGF3YWl0JUUzJTgyJUI1JUUzJTgzJUIzJUUzJTgzJTk3JUUzJTgzJUFCJUU1JUE0JTlBJUUzJTgyJTgxJUUzJTgxJUE3JUU0JUI4JTgxJUU1JUFGJUE3JUUzJTgxJUFCJUUzJTgyJThGJUUzJTgxJThCJUUzJTgyJThBJUUzJTgyJTg0JUUzJTgxJTk5JUUzJTgxJThGJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmcz1hMGU0MTU2ZTI3MDkxZmZlODQwZjhkMjYyZGI5NjE2OQ&mark-x=142&mark-y=57&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZoPTc2Jnc9NzcwJnR4dD0lNDBCYXNoaTUwJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9MzYmdHh0LWFsaWduPWxlZnQlMkN0b3Amcz00ZjNjNzJlMzcyY2NhMGYxMTQ3Nzg3ZDdlZTQ0ZTU4NA&blend-x=142&blend-y=486&blend-mode=normal&s=417fb0e48b4907124bd3d810b74fdad9)
そのため、Promise
やasync
/await
といったより便利な方法も開発されています。
Promise
Promiseとは、非同期処理の結果を表すオブジェクトのことです。
Promiseオブジェクトは、pending
(未決定)、fulfilled
(成功)、rejected
(失敗)の3つの状態を持ちます。
非同期処理が完了すると、Promiseオブジェクトはその状態に応じてthen
メソッドやcatch
メソッドで登録したコールバック関数を実行します。
1 2 3 4 5 6 7 8 |
// HTTPリクエストを送る fetch("https://example.com/api/data") // レスポンスをJSONに変換する .then(response => response.json()) // データを表示する .then(data => console.log(data)) // エラーがあれば表示する .catch(error => console.error(error)); |
上記のコードでは、fetch
関数でHTTPリクエストを送り、その結果をPromiseオブジェクトとして受け取っています。
その後、then
メソッドでレスポンスをJSON形式に変換し、もう一度then
メソッドでデータを表示します。
もしエラーが発生したらcatch
メソッドでエラーメッセージを表示します。
Promiseのサンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// 非同期処理(1秒後にHello World!と表示し、成功状態(resolve)にする) function asyncFunc() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Hello World!"); resolve(); // 成功状態 }, 1000); }); } // 非同期処理(1秒後にGoodbye!と表示し、成功状態(resolve)にする) function asyncFunc2() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Goodbye!"); resolve(); // 成功状態 }, 1000); }); } // 非同期処理を順番に実行する(thenメソッドでPromiseの結果を受け取る asyncFunc().then(asyncFunc2) // Hello World! -> Goodbye! |
async/await
async/awaitとは、非同期処理をよりシンプルに書くための構文です。async
/await
はPromiseをベースにしていますが、then
メソッドやcatch
メソッドを使わずに、同期処理のように記述できますが、async
/await
を使うには以下の2つのステップが必要です。
- 非同期処理をする関数の前にasyncキーワードを付ける。
これでその関数はPromiseオブジェクトを返すようになる。 - Promiseオブジェクトを返す関数の前にawaitキーワードを付ける。
これでその関数の結果が返されるまで待機するようになる。
例えば、以下のコードでは、fetch
関数でHTTPリクエストを送り、その結果をJSON形式に変換し、データを表示します。
エラーが発生したらtry…catch
文でエラーメッセージを表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 非同期処理をする関数 async function getData() { try { // HTTPリクエストを送り、レスポンスを待つ const response = await fetch("https://example.com/api/data"); // レスポンスをJSONに変換し、データを待つ const data = await response.json(); // データを表示する console.log(data); } catch (error) { // エラーがあれば表示する console.error(error); } } // 関数を呼び出す getData(); |
async
/await
は非同期処理の可読性や効率性が向上しますが、Promiseと同じく非同期処理の仕組みや挙動は理解しておく必要があります。
async/awaitのサンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 非同期処理(1秒後にHello World!と表示し、成功状態(resolve)にする) function asyncFunc() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Hello World!"); resolve(); // 成功状態 }, 1000); }); } // 非同期処理(1秒後にGoodbye!と表示し、成功状態(resolve)にする) function asyncFunc2() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Goodbye!"); resolve(); // 成功状態 }, 1000); }); } // 非同期処理を順番に実行する(async/await構文でPromiseの結果を待つ) async function main() { await asyncFunc(); // Hello World! await asyncFunc2(); // Goodbye! } main(); |
以上がJavaScriptの非同期処理についての解説とサンプルコードです。
ご参考になれば幸いです。
もっと詳しい解説はこちらをご参考ください。
![](https://minory.org/wp-content/plugins/pochipp/assets/img/pochipp-logo-t1.png)
![](https://minory.org/wp-content/plugins/pochipp/assets/img/pochipp-logo-t1.png)
コメント