JavaScriptにおける解決済みPromiseの作成
時には、既に完了したPromiseを作成する必要があるかもしれません。そのためには2つのメソッドがあります: Promise.resolveメソッドは成功裏に解決されたPromiseを作成し、Promise.rejectメソッドは拒否されたPromiseを作成します。これらのメソッドはパラメータとして、それぞれPromiseの結果またはエラーとなるものを受け取ります。
既に完了したPromiseはいつ必要になるのでしょうか?例を見てみましょう。ある関数があり、パラメータとして数値を受け取り、非同期に何らかの処理を行い、結果のPromiseを返すとします:
function func(num) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
}
この関数を次のように使用します:
func(5).then(function(res) {
console.log(res); // 25を出力
});
ここで、渡された数値が0より大きい場合にのみ非同期操作を実行し、それ以外の場合、関数の結果は0でなければならないと決めたとします:
function func(num) {
if (num > 0) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
} else {
return 0; // ゼロ結果
}
}
しかし、これでは関数がPromiseまたは数値を返すことになります。その結果、関数の結果にthenメソッドを適用できなくなります。なぜなら、関数が数値を返す場合、エラーが発生するからです:
func(0).then(function(res) { // エラー、数値0に対してthenメソッドを適用している
});
この問題を解決するにはPromise.resolveが役立ちます:
function func(num) {
if (num > 0) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
} else {
return Promise.resolve(0); // 数値ではなくPromiseを返す
}
}
次に、渡された値が0の場合は0を返し、0未満の数値の場合は例外を発生させることに決めたとします。この場合、Promise.rejectメソッドが役立ちます:
function func(num) {
if (num > 0) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
} else if (num === 0) {
return Promise.resolve(0);
} else {
return Promise.reject('incorrect number'); // 拒否されたPromiseを返す
}
}