Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
13
Help us understand the problem. What is going on with this article?
@chihiro

【javascript】Promiseについて学ぶ①

More than 3 years have passed since last update.

Promiseについてまとめます。

Promiseとは

非同期処理をわりかしすっきり書くことができる書き方。
わりかしと書いたのは、コールバックを駆使して書くよりもすっきり書くことができるという意味です。

Promiseの基本

Promiseを使うときの基本手順です。

1.Promiseコンストラクタに非同期に処理したいことを書いたコールバックを引数として渡し、オブジェクト化する

newしてオブジェクト化することができます。
コールバック関数には、引数にresolve、rejectを渡す必要があります。

2.成功時はresolve、失敗時はrejectを呼ぶ

非同期処理では、処理が成功したときはresolve、失敗したときはrejectを呼び出します。

3.Promiseオブジェクトをリターンする

4.成功時、失敗時に関数を実行したいのならば、then()メソッドを使う

Promiseオブジェクトに対してthen()を使用することで、成功時、失敗時に実行したい関数を登録することができます。

以下、サンプルコードを用いて詳しく説明します。

sample.js

1   function asyncFunc() {
2       return new Promise(function (resolve, reject) { // 手順1、3
3           // ここ以下に非同期に処理したい内容を書きます
4           async(function(err, data){ // 仮想の関数です。
5               if (err) {
6                   reject(err);  // 手順2 失敗したのでrejectを呼び出す
7               
8               }
9               resolve(data);  // 手順3 成功したのでresolveを呼び出す
10           });
11      });
12  }
13  
14  function onFulfilled(data) {
15    console.log(data);
16  }
17  
18  function onRejected(err) {
19    console.log(err);
20  }
21 
22  asyncFunc().then(onFulfilled, onRejected);  // 手順4
23 

L2: return new Promise(function (resolve, reject) {・・・

new Promise(callback)でPromiseオブジェクトを作ることができます。
callbackには非同期に処理したいことを書きます。
また、このcallbackでは引数にresolveとrejectを渡す必要があります。
newでオブジェクトを作り、returnすることで、asyncFunc関数を実行したとき(L22)にPromiseオブジェクトを返すようにします。

L6: reject(err);

ここでは仮想のasync関数を使用しています。
errがあった場合、処理は失敗とします。そのときに、rejectを呼び出します。

L9: resolve(data);

errがなかった場合、処理は成功とします。そのときにresolveを呼び出します。

L22: asyncFunc().then(onFulfilled, onRejected);

then関数を使用することによって、成功時、失敗時に実行する関数を登録することができます。
asyncFunc関数の戻り値はPromiseオブジェクトですので、then()はインスタンスメソッドです。
成功時にはonFulfilledが実行され、失敗時にはonRejectedが実行されます。
ここでいう、成功時、失敗時というのはそれぞれ、非同期処理中にresolve、rejectが呼ばれた時のことです。

L14~22 以下のようにも書けます

sample-then.js
1  asyncFunc().then(function (data) {
2      console.log(data);  // onFulfilled
3  }, function (err) {
4      console.log(err);  // onRejected
5  });

L14~22 catchを使って以下のようにも書けます

sample-catch.js
1  asyncFunc().then(function(data) {
2      console.log(data);
3  }).catch(function(err) {
4      console.log(err);
5  });

.catch()については、.then(undefined, onRejected)と同じ意味になります。

Promiseオブジェクトの状態

インスタンス化したPromiseのオブジェクトには3つの状態があります。

  • Fulfilled
    • 成功したとき。すなわちresolveされたとき。このときonFulfilledが呼ばれる
  • Rejected
    • 失敗したとき。すなわちrejectされたとき。このときonRejectedが呼ばれる
  • Pending
    • FulfilledでもRejectedでもないとき。初期状態等が含まれる。

非同期処理の中で成功と判断したときにresolve()を呼び出す→Fulfilledの状態になる
非同期処理の中で失敗と判断したときにreject()を呼び出す→Rejectedの状態になる
ということのようですね。

resolveされたときはthen()の第1引数に渡された関数が実行されます。
rejectされたときはthen()の第2引数に渡された関数、もしくはcatch()に渡した関数が実行されます。

thenとcatch

rejectされたときの関数の実行について、then()とcatch()だと動きが異なります。

sample-then.js
1  asyncFunc().then(function (data) {
2      console.log('onFulfilled' + data);  // onFulfilled
3  }, function (err) {
4      console.log('onRejected' + err);  // onRejected
5  });

上記のsample-then.jsの場合、asyncFunc関数でRejected状態になったときにL4が実行されます。
また、asyncFunc関数でFulfilled状態になったときは、L2が実行されます。このL2が実行されているときにエラーが起きた場合(このコードだと発生しませんが・・・)には、L4は実行されません。

sample-catch.js
1  asyncFunc().then(function(data) {
2      console.log('onFulfilled' + data);
3  }).catch(function(err) {
4      console.log('onRejected' + err);
5  });

上記のsample-catch.jsの場合、asyncFunc関数でRejected状態になったときにはsample-then.jsと同様、L4が実行されます。
また、asyncFunc関数でFulfilled状態になったときも同様に、L2が実行されています。
ですが、L2が実行中にエラーが起こった場合もL4が実行されます。この点がthenを使ったときと違う動きとなります。

上記のようなそれぞれの動きに違いを考えて、使用する必要があります。

今回はここまでとします。
次はall()についてまとめようと思います。

13
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
chihiro
jrits
信頼と魅力のある先進のITをもとに、お客様のワークスタイル・イノベーションの実現を目指します。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
13
Help us understand the problem. What is going on with this article?