JavaScriptの非同期処理:Promiseによる並行と直列処理の最適な実装方法
【免费下载链接】JavaScriptTrainingTraining course repository for JavaScript项目地址: https://gitcode.com/gh_mirrors/ja/JavaScriptTraining
JavaScriptの非同期処理は現代のWeb開発において欠かせない技術です。特にAPI通信やファイル読み込みなどの時間のかかる処理を効率的に扱うためには、Promiseを活用した並行処理と直列処理の実装方法をマスターする必要があります。この記事では、初心者でも理解しやすいように、Promiseを使った非同期処理の基本から応用までを解説します。
Promiseの基本:非同期処理の基礎
PromiseはJavaScriptにおける非同期処理を扱うためのオブジェクトです。非同期処理の状態(進行中、成功、失敗)を表し、処理の完了時に結果を返します。Promiseには主に3つの状態があります:
- pending(進行中):処理がまだ完了していない状態
- fulfilled(成功):処理が正常に完了した状態
- rejected(失敗):処理がエラーで終了した状態
Promiseを作成するには、new Promise()コンストラクタを使用します。コンストラクタにはコールバック関数を渡し、その中で非同期処理を記述します。例えば、一定時間後に値を返すPromiseは以下のように作成できます:
function createWaitPromise(value, msec) { return new Promise(function(resolve) { setTimeout(resolve, msec, value); }); }この関数は、指定したミリ秒後にvalueを返すPromiseを作成します。resolve関数は、Promiseを成功状態にし、結果を渡すために使用されます。
thenメソッド:Promiseの結果を処理する
Promiseが成功状態(fulfilled)になったときに実行される処理は、thenメソッドを使って定義します。thenメソッドはコールバック関数を受け取り、その引数にPromiseの結果が渡されます。
例えば、以下のコードはPromiseが解決されたときにメッセージを表示します:
var promise = Promise.resolve('resolved!'); promise.then(function(msg) { console.log(msg); // 'resolved!' が表示される });thenメソッドは新しいPromiseを返すため、チェーンすることができます。これにより、複数の非同期処理を順番に実行する直列処理を実現できます。
catchメソッド:エラー処理を行う
Promiseが失敗状態(rejected)になったときに実行される処理は、catchメソッドを使って定義します。catchメソッドはエラーを引数に取るコールバック関数を受け取ります。
例えば、以下のコードはPromiseが拒否されたときにエラーメッセージを表示します:
var promise = Promise.reject('rejected!'); promise.catch(function(msg) { console.log(msg); // 'rejected!' が表示される });thenメソッドの第2引数としてエラーハンドラーを指定することもできますが、catchメソッドを使用する方が可読性が高く推奨されています。
Promise.all:複数のPromiseを並行処理する
複数の非同期処理を並行して実行し、すべての処理が完了したら結果をまとめて取得するには、Promise.allメソッドを使用します。Promise.allはPromiseの配列を受け取り、すべてのPromiseが解決されたときにそれぞれの結果を配列として返す新しいPromiseを作成します。
例えば、以下のコードは3つのPromiseを並行処理し、すべての結果を取得します:
var messageFragments = ['あなたと', 'java', '今すぐダウンロード']; var promise1 = createWaitPromise(messageFragments[0], 10); var promise2 = createWaitPromise(messageFragments[1], 20); var promise3 = createWaitPromise(messageFragments[2], 30); var promise = Promise.all([promise1, promise2, promise3]); promise.then(function(results) { console.log(results); // ['あなたと', 'java', '今すぐダウンロード'] が表示される });Promise.allは、すべてのPromiseが成功するまで待機します。一つでもPromiseが拒否された場合、直ちに拒否されたPromiseのエラーを返します。
Promise.race:最も速く完了したPromiseを取得する
複数の非同期処理の中で、最も速く完了した処理の結果を取得するには、Promise.raceメソッドを使用します。Promise.raceはPromiseの配列を受け取り、最初に解決または拒否されたPromiseの結果を返す新しいPromiseを作成します。
例えば、以下のコードは3つのPromiseの中で最も速く完了したものの結果を取得します:
var messageFragments = ['30億の', 'デバイスで', '走るjava']; var promise1 = createWaitPromise(messageFragments[0], 30); var promise2 = createWaitPromise(messageFragments[1], 10); var promise3 = createWaitPromise(messageFragments[2], 30); var promise = Promise.race([promise1, promise2, promise3]); promise.then(function(result) { console.log(result); // 'デバイスで' が表示される(最も速く完了したpromise2の結果) });Promise.raceは、最初に完了したPromiseが成功した場合にはその結果を、失敗した場合にはそのエラーを返します。
直列処理 vs 並行処理:最適な実装方法
非同期処理を実装する際には、直列処理と並行処理のどちらを使用するかを判断する必要があります。以下にそれぞれの適用シーンと実装方法を説明します。
直列処理:処理を順番に実行する
前の処理の結果に依存する場合や、処理を順番に実行する必要がある場合には直列処理を使用します。直列処理はthenメソッドをチェーンすることで実現できます。
例えば、APIからデータを取得し、そのデータを加工して再びAPIに送信する場合などに直列処理が適しています:
fetch('/api/data') .then(function(response) { return response.json(); }) .then(function(data) { return processData(data); // データを加工する関数 }) .then(function(processedData) { return fetch('/api/data', { method: 'POST', body: JSON.stringify(processedData) }); }) .then(function(response) { console.log('データが正常に送信されました'); }) .catch(function(error) { console.error('エラーが発生しました:', error); });並行処理:処理を同時に実行する
処理が互いに依存せず、同時に実行できる場合には並行処理を使用します。並行処理はPromise.allメソッドを使用することで実現できます。
例えば、複数のAPIからデータを並行して取得する場合に並行処理が適しています:
var promise1 = fetch('/api/data1').then(function(response) { return response.json(); }); var promise2 = fetch('/api/data2').then(function(response) { return response.json(); }); var promise3 = fetch('/api/data3').then(function(response) { return response.json(); }); Promise.all([promise1, promise2, promise3]) .then(function(results) { var data1 = results[0]; var data2 = results[1]; var data3 = results[2]; // データを統合する処理 }) .catch(function(error) { console.error('エラーが発生しました:', error); });並行処理を使用することで、処理全体の所要時間を短縮することができます。
実践的な非同期処理の例:fetch APIとの組み合わせ
Web開発でよく使用される非同期処理の例として、fetch APIを使ったデータ取得があります。fetch APIはPromiseベースで実装されており、非同期でAPI通信を行うことができます。
例えば、以下のコードは/api/friends/Sugarから友人の一覧を取得する処理を実装しています:
var api = '/api/friends/'; var username = 'Sugar'; var promisedFriends = fetch(api + username) .then(function(res) { return res.json(); }); promisedFriends.then(function(friends) { console.log(friends); // ['PYXC-PJ'] が表示される });このように、fetch APIとPromiseを組み合わせることで、簡潔かつ効率的に非同期処理を実装することができます。
まとめ:Promiseを活用した非同期処理のポイント
JavaScriptの非同期処理において、Promiseは非常に強力なツールです。以下に、Promiseを活用した非同期処理のポイントをまとめます:
- Promiseの基本:
new Promise()でPromiseを作成し、resolveとrejectで状態を制御する - then/catchメソッド:
thenで成功時の処理、catchでエラー時の処理を定義する - 並行処理:
Promise.allで複数のPromiseを並行して実行し、すべての結果を取得する - 最速処理:
Promise.raceで最も速く完了したPromiseの結果を取得する - 直列処理:
thenメソッドをチェーンすることで、処理を順番に実行する
これらのポイントを理解し、適切な場面で使い分けることで、効率的な非同期処理を実装することができます。ぜひ実際のプロジェクトでPromiseを活用してみてください!
非同期処理の練習には、public/stage5/tests.jsにあるサンプルコードが役立ちます。このファイルには、Promiseの基本から応用までの練習問題が含まれています。
JavaScriptの非同期処理は初心者にとって難しい概念ですが、Promiseをマスターすることで、より高度なWebアプリケーションの開発が可能になります。ぜひこの記事を参考に、Promiseの使い方を練習してみてください! 🚀
【免费下载链接】JavaScriptTrainingTraining course repository for JavaScript项目地址: https://gitcode.com/gh_mirrors/ja/JavaScriptTraining
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考