前提
実務で入る前にはあんまり知らなかったのですが、実務に入ると当たり前のように使っているPromise。フロントエンドの方はもちろん、バックエンド志望の方でもJavascriptの知識は必要不可欠になっています。
そこで今回は「Promise」についてまとめてみたいと思います。
1. Promiseとは
Promiseとは、オブジェクトであり、非同期の結果を返します。
非同期メソッドは結果の値を返す代わりに、未来のある時点で値を提供するプロミスを返すことで、同期メソッドと同じように値を返すことができるようになります。
promiseの状態は以下のいずれかになります。
- pending (待機) 初期状態。まだ、処理が完了していない状態です。
- fullfilled (履行) 処理が成功して完了した。
- pending (拒否) 処理が失敗した。
2. 簡単なPromiseを作成して .then()でPromiseを処理するパターン
ここでは簡単なPromiseを作成して実際にコードで確認していきましょう!
const samplePromise = new Promise((resolve, reject) => {
// testは常にtrueなので、このPromiseの処理は常に成功します。
const test = true;
if (test) {
// 処理が成功したら、'Sucess'という文字列を返すと定義する。
resolve('Success');
} else {
// 処理が失敗したら、'Failed'という文字列を返すと定義する。
reject('Failed');
}
})
// Promiseを処理。
samplePromise.then(res => {
// Promiseが成功した時に呼ばれる関数ブロック
console.log(res); //"Success"。
}).catch(error => {
// Promiseが失敗した時に呼ばれる関数ブロック
console.log(error)
})
3. then()のメソッドチェーンを使ってみる
.then()は以下のコードのように繋げて書くこともできます。
then()が返すものはPromiseオブジェクトであるので、チェーンで繋げることも可能です。
then()の中でreturn (値)することは、resolve(値)と等しくなります。
一方で何もreturnしないと気はresolveになるのでundefinedとなります。
const samplePromise = new Promise((resolve, reject) => {
// testは常にtrueなので、このPromiseの処理は常に成功します。
const test = true;
if (test) {
// 処理が成功したら、'Sucess'という文字列を返すと定義する。
resolve('Success');
} else {
// 処理が失敗したら、'Failed'という文字列を返すと定義する。
reject('Failed');
}
})
// Promiseを処理。
samplePromise.then(
res => {
console.log(res) // "Success"
return "OK";
}
).then(
res => console.log(res) // "OK"。一つ前のチェーンで"OK"をリターンしているので。
).then(
res => console.log(res) // undefined。一つ前のチェーンで何も返していないので。
)
次はこの処理をrejectしてみましょう。
then()をスキップして、 .catch()に入ります
const samplePromise = new Promise((resolve, reject) => {
// rejectさせます。
const test = false;
if (test) {
// 処理が成功したら、'Sucess'という文字列を返すと定義する。
resolve('Success');
} else {
// 処理が失敗したら、'Failed'という文字列を返すと定義する。
reject('Failed');
}
})
// Promiseを処理。
samplePromise.then(
res => {
console.log(res)
return "OK";
}
).then(
res => console.log(res)
).then(
res => console.log(res)
).catch(err => console.log(err)) //"Failed"
4. Promise.resolve
Promise.resolveは、 new Promiseのショートハンドでの記法です。仕組みは同じですが、書き方をシンプルにしただけです。
Promise.resove('よろしく').then((res) => console.log(res)); // よろしく
new Promise((resolve) => resolve('よろしく')).then((res) => console.log(res)); // よろしく
以上をまとめると、Promise.resolveとは「渡した値でFulfilledされるpromiseオブジェクトを返すメソッド」となります。
上記のコードは、共にPromise Objectをリターンしますので、コンソールで確認してみましょう!
5. Promise.reject
今度は、rejectバージョンで書いてみます。
new Promise((resolve, reject) => {
reject(new Error('エラー'); // Uncaught (in promise) Error
});
Promise.reject(new Error("エラー")).catch((error) => {
console.error(error); // Error: エラー
});
6. Promise.finally()
Promise.finally()は成功と失敗時のどちらのケースでも呼び出したい時に使うのが最適です。
注意するところが、
.then()は違い finally()のコールバック関数は引数を受け取りません。
function onFinally() {
// 成功、失敗どちらでも実行したい処理をかく
// 'final'というストリングをリターンしてみます。
return 'final'
}
// `Promise#finally` は新しいpromiseオブジェクトを返す
Promise.resolve(777)
.finally(onFinally)
.then((value) => {
// 呼び出し元のpromiseオブジェクトの状態をそのまま引き継ぐので `777` で resolveされている.
// then メソッドとは違い、.finally()メソッド内で値をリターンしてもPromise チェーンには影響なし。
// `final`はリターンされない。
console.log(value); // 777
});
7. まとめ
ざっくりとPromiseまとめてみました。シンプルな例を出しましたが、実務に入って難しいなと思ったら
簡単なものでも良いのでアウトプットしてみると良いと思います!