LoginSignup
1
6

More than 3 years have passed since last update.

書いて覚えるPromise

Posted at

Promiseとは?

Promiseは非同期処理の完了or失敗を表すオブジェクト。

  • 非同期処理の成功(resolve)、失敗(reject)を表すオブジェクト
  • thencatch, finallyメソッドを使うことで非同期処理後に関数を実行することができる
  • Promise.allPromise.raceを使えば、非同期処理を並列で実行することができる

Promiseを使った処理を書いてみよう

resolve(成功)の例

  • 非同期処理が成功した場合は、resolve(結果の値) を呼ぶ
  • 非同期処理成功後に行いたい処理は、then()メソッドに関数を渡すことで実現できる
new Promise((resolve, reject) => {
  setTimeout(() => {
    // 成功する例なので、resolveを返す
    resolve('非同期処理 成功!!');
  }, 3000);
}).then((value) => {
  console.log('=== thenメソッド内 ===');
  console.log('resolveされた値: ' + value);
}).catch((value) => {
  console.log('=== catchメソッド内 ===');
  console.log('rejectされた値: ' + value);
});
  • 実行結果
$ node promise.js
=== thenメソッド内 ===
resolveされた値: 非同期処理 成功!!

reject(失敗)の例

  • 非同期処理が失敗した場合は、reject(Errorオブジェクト)を呼ぶ
  • 非同期処理失敗時に実行したい処理は、catch()メソッドに関数を渡すことで実現できる
new Promise((resolve, reject) => {
  setTimeout(() => {
    // 失敗する例なので、rejectを返す
    reject(new Error('非同期処理 失敗.....'));
  }, 3000);
}).then((value) => {
  console.log('=== thenメソッド内 ===');
  console.log('resolveされた値: ' + value);
}).catch((value) => {
  console.log('=== catchメソッド内 ===');
  console.log('rejectされた値: ' + value);
});
  • 実行結果
=== catchメソッド内 ===
rejectされた値: Error: 非同期処理 失敗.....

finally 成功しても、失敗しても実行する処理の例

成功しても、失敗しても実行したい処理は、finally()に関数を渡すことで実現できる。


new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('非同期処理 失敗.....'));
  }, 3000);
}).then((value) => {
  console.log('=== thenメソッド内 ===');
  console.log('resolveされた値: ' + value);
}).catch((value) => {
  console.log('=== catchメソッド内 ===');
  console.log('rejectされた値: ' + value);
}).finally(() => {
  console.log('=== finallyメソッド内 ===');
  console.log('DONE!!')
});
  • 実行結果
=== catchメソッド内 ===
rejectされた値: Error: 非同期処理 失敗.....
=== finallyメソッド内 ===
DONE!!

非同期処理の並列実行の例

Promise.all

  • Promise.all()にPromiseオブジェクトの配列を渡す
  • 全てresolve(成功)した時に、then()が実行される
  • どれか1つでもreject(失敗)した時は、catch() が実行される

例えば、2つのAPIを叩いて、2つとも成功したときに何か処理をするみたいなことをしたい場合は、


const postAPI1 = new Promise((resolve, reject) => {
  console.log('API1を叩く');
  setTimeout(() => {
    resolve('API1成功');
  }, 3000);
})

const postAPI2 = new Promise((resolve, reject) => {
  console.log('API2を叩く');
  setTimeout(() => {
    resolve('API2成功');
  }, 200);
})

Promise.all([postAPI1, postAPI2]).then((values) => {
  console.log('=== thenメソッド内 ===')
  console.log(values);
});
  • 実行結果
API1を叩く
API2を叩く
=== thenメソッド内 ===
[ 'API1成功', 'API2成功' ]

Promise.race

  • Promise.race()にPromiseオブジェクトの配列を渡す
  • 1つでもresolve(成功), reject(失敗)が呼び出されたら、thenもしくはcatchが実行される
  • thencatchメソッドには最初に完了した処理の値が渡される
const postAPI1 = new Promise((resolve, reject) => {
  console.log('API1を叩く');
  setTimeout(() => {
    reject(new Error('API1失敗'));
  }, 3000);
})

const postAPI2 = new Promise((resolve, reject) => {
  console.log('API2を叩く');
  setTimeout(() => {
    resolve('API2成功');
  }, 200);
})

// postAPI2の方がsetTimeoutを短めに設定しているので、先に処理が完了する。
// そのためthenの処理が実行される。
Promise.race([postAPI1, postAPI2])
  .then((value) => {
    console.log('=== thenメソッド内 ===');
    console.log(value);
  }).catch((value) => {
    console.log('=== catchメソッド内 ===');
    console.log(value);
  });
  • 実行結果
API1を叩く
API2を叩く
=== thenメソッド内 ===
API2成功

参考

1
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6