Promiseとは何か
Promiseは、未来のある時点で値を返すことを約束するオブジェクトです。非同期処理の結果をより扱いやすくするために設計されました。
従来の非同期処理では、処理が完了したときに実行する関数(コールバック関数)を直接渡していましたが、Promiseでは関数が返したオブジェクトに対してコールバックを登録する仕組みになっています。
従来のコールバック方式との比較
従来のコールバック方式では、非同期処理を行う関数に直接コールバック関数を渡していました。
// 従来のコールバック方式
function asyncOperation(callback) {
setTimeout(function() {
callback('処理完了');
}, 2000);
}
asyncOperation(function(result) {
console.log(result);
});
一方、Promise方式では関数がPromiseオブジェクトを返し、そのオブジェクトに対してコールバックを登録します。
// Promise方式
function asyncOperation() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('処理完了');
}, 2000);
});
}
asyncOperation().then(function(result) {
console.log(result);
});
この違いにより、エラーハンドリングがシンプルになり、複数の非同期処理を連鎖させやすくなります。
Promiseオブジェクトの作成方法
resolveとrejectの役割
Promiseオブジェクトを作成するには、new Promise()を使用します。この際、コンストラクタには関数を渡しますが、この関数は2つの引数を受け取ります。
- resolve: 非同期処理が成功したときに呼び出す関数。成功時の値を引数として渡します
- reject: 非同期処理が失敗したときに呼び出す関数。失敗時の値(通常はエラー)を引数として渡します
基本的な実装例
実際にPromiseオブジェクトを作成してみましょう。以下の例では、50%の確率で成功または失敗する非同期処理をシミュレートしています。
function asyncOperation() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
// 50%の確率で成功か失敗を返す例
if (Math.random() > 0.5) {
resolve('Async operation complete');
} else {
reject('Async operation failed');
}
}, 2000);
});
}
asyncOperation()
.then(function(result) {
console.log(result); // "Async operation complete"
})
.catch(function(error) {
console.error(error); // "Async operation failed"
});
この例では、2秒後にランダムにresolveまたはrejectが呼び出されます。
thenメソッドとcatchメソッドの使い方
thenメソッドで成功時の処理を登録
thenメソッドは、Promiseが解決された(成功した)ときに実行されるコールバックを登録します。resolveで渡した値が、thenのコールバック関数の引数として渡されます。
promiseFunction()
.then(function(result) {
// resolveで渡された値がresultに入る
console.log(result);
});
catchメソッドでエラーハンドリング
catchメソッドは、Promiseが拒否された(失敗した)ときに実行されるコールバックを登録します。rejectで渡した値が、catchのコールバック関数の引数として渡されます。
promiseFunction()
.catch(function(error) {
// rejectで渡された値がerrorに入る
console.error(error);
});
thenとcatchは連鎖して記述できるため、成功時と失敗時の処理を分かりやすく書けますね。
Promiseの重要な特徴
thenメソッドが使えるのはPromiseオブジェクトだけ
thenメソッドは、Promiseオブジェクトにのみ存在するメソッドです。通常の関数の戻り値に対しては使用できません。
// 通常の関数 - thenは使えない
function normalFunction() {
return 'Hello';
}
// normalFunction().then() // エラー: normalFunction().then is not a function
// Promiseを返す関数 - thenが使える
function promiseFunction() {
return new Promise(function(resolve, reject) {
resolve('Hello from Promise');
});
}
promiseFunction().then(function(result) {
console.log(result); // "Hello from Promise"
});
この違いを理解しておくことは重要です。thenメソッドを使いたい場合は、必ずPromiseオブジェクトを返す関数を作成する必要があります。
まとめ
Promiseは非同期処理をより扱いやすくするための仕組みです。主なポイントは以下の通りです。
- Promiseは未来の値を表すオブジェクト
-
resolveで成功時の値、rejectで失敗時の値を定義 -
thenメソッドで成功時の処理を登録 -
catchメソッドで失敗時の処理を登録 -
thenメソッドはPromiseオブジェクトにのみ使用可能
従来のコールバック方式と比較しながら学習することで、Promiseの利点がより明確になります。実際のコードで試しながら、Promiseの動作を確認してみましょう。