🙆‍♂️

JavascriptのPromiseについてざっくりまとめてみた!

2021/10/18に公開

前提

実務で入る前にはあんまり知らなかったのですが、実務に入ると当たり前のように使っている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まとめてみました。シンプルな例を出しましたが、実務に入って難しいなと思ったら
簡単なものでも良いのでアウトプットしてみると良いと思います!

Discussion