概要
今まで同期処理を書くときはasync/awaitで何となくわかった気になりながら実装していましたが、最近Promiseベースで書かれたコードをがっつり読む機会があり、実際何をやっているのかよく分からなかったのでこれを機にPromiseについて調べてみました。
本記事ではその調べた内容を共有していきます。
この記事で分かること
- Promiseって?
- Promiseの使い方
Promiseって?
特定の処理の終了を待つ(同期処理をする)ために使われるオブジェクトです。
Promiseオブジェクトを生成する際は下記のように引数に何かしらの処理を渡してやります。
new Promise((resolve, reject) => {
// 何らかの処理
})ここでresolve,rejectというものが出てきましたが、これらは処理の終了状態と返り値を通知するもので、以下のように使い分けられます。
| メソッド | 終了状態 |
|---|---|
| resolve | 正常終了 |
| reject | 異常終了(エラーとは限らない) |
この通知を受け取ると後続処理に処理が移るのですが、Promiseオブジェクトにはそのために使えるメソッドがいくつかあります。
その中から基本的なものを3つを用途別にまとめると以下のようになります
| メソッド | 実行条件 |
|---|---|
| then | resolveされたとき |
| catch | rejectされたとき |
| finally | resolve,rejectに関わらず必ず |
これらのメソッドを使用することでPromiseオブジェクトの処理の完了後に何らかの処理を実行するということができるようになります。
それぞれのメソッドは実行条件は異なりますが、何らかの処理を待って後続処理を実行するという点では本質的には同じです。
new Promise((resolve, reject) => {
// 処理1
}).then(() => { // 処理1がresolveで完了したら処理2を実行する
// 処理2
})Promiseの使い方
実際にコードを見ながらPromiseの書き方を確認しましょう。
以下のコードはtest()の実行完了後にコンソールにログを出力しようとしています。
const test = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("test1"); // 一秒後に「test1」という文字列を返して、処理を完了する
}, 1000);
});
};
test().then((res) => {
console.log(res, " finished!!!"); // test1 finished!!!
});test()の定義を見るとnew Promise()でPromiseオブジェクトのインスタンスを生成し、そのインスタンスに渡されたsetTimeout()処理を待って、returnでその返り値を返しています。
returnで返される値は今回の例ではresolve()の中の「test1」という文字列になります。
これはreject()の場合も同様で、以下のような場合「test1」という文字列がreturnされます。
return new Promise((reject) => {
setTimeout(() => {
reject("test1");
}, 1000);
});もちろんresolve()、reject()は同時に使用することもできます。
return new Promise((resolve, reject) => {
if ({ 条件式 }) {
setTimeout(() => {
resolve("test1");
}, 1000);
} else {
setTimeout(() => {
reject("test2");
}, 1000);
}
});最後にthen()メソッドがtest()がreturnした返り値を受け取り後続処理を実行します。
test().then((res) => { // test()からの返り値(「test1」という文字列)をresに入れる
console.log(res, " finished!!!"); // test1 finished!!!
});
以上がPromiseを使った同期処理の書き方の基本になります。
まとめ
Promiseとは特定の処理の終了を待つためのオブジェクトでした。
処理の終了を通知するメソッドとして
resolve→ 正常終了reject→ 異常終了(エラーとは限らない)
があり、それらの通知を受け取って後続処理を実行するためのメソッドとして、
then→resolveされたときcatch→rejectされたときfinally→resolve,rejectに関わらず必ず
がありました。
Promiseオブジェクト内でresolve or rejectされたら、その内容に応じてthen or catch もしくは常時finallyが実行されるといった形で同期処理ができるよというのが、Promiseになります。