ノンプログラマーがjavascript promiseを勉強してみた 前編

ノンプログラマーがjavascript promiseを勉強してみた 前編

こんばんわ、taisonです。

先日pwa(プログレッシブウェブアプリ)を使ってみようと思って、pwaのチュートリアル記事を見て勉強していたんですが、自分自身プログラマーではない(webサイトとかwordpressに関わる言語を編集できるくらいの知識しかない)ので、色々とハマる部分がありました。

なんとかチュートリアル終了までこぎつけたんですが、これを使って何かwebアプリを自作しようと思うと色々必要な知識が見えてきたので、一つずつ解決していこうと思っています。

今回はその第一弾!
pwaのほかストレージの役割をするindexedDBにも使われているPromiseの概念や使い方を記事にしていきます。

javascript Promiseとは何か?

で、Promiseってなんぞや?って話なんですが、Promiseはjavascriptを非同期処理で使う時、コードがぐちゃぐちゃにならないようにするAPIのことです。

よく分かんないですよね 笑

順番に紐解いていくと、まず非同期処理

通常javascriptは処理を実行するとき、上から順にコードを読んで処理をかけていきます。
処理を飛ばすことはできないので、時間がかかる処理の場合、処理が完了するまで待機をします。

なんだか待ってる時間がもったいないですよね、、、

じゃあこの待つ時間を他の処理にあてて、処理が完了したら元の処理ルートに戻しましょう
というのが非同期処理です。図解すると下記のような感じ。

非同期処理イメージ

この非同期処理。マルチタスク的な感じで処理を早くするのに一役買うんですが、ある程度処理が複雑になってくると、コードの書き方が入れ子の連続になってしまい、コードがどんどん読みにくくなってしまうみたいなんですね。

そこを解決しよう!と用いられるようになったのが、このPromiseなのです。

実際pwaのチュートリアルコードを見てると、このPromiseで使うメソッドやらが登場していて、その概念が組み込まれていることがよく分かります。

pwaに手ぇ出すならまずPromiseを超えていけ。と言わんばかりに。

Promiseの使い方

さて、そんなPromiseの使い方ですが、構造自体は単純明快。ですが、ノンプログラマーには派生させるまでに時間がかかりそうです。
まあ、javascriptの基本が備わってないから当然といえば当然ですが、、、
なので、ここも概念から理解をしていきましょう。

まず、Promiseがどうやって非同期処理を簡略化させるか。その構造を紐解いてみたいと思います。

Promiseの基本

Promiseがどうやって処理コードを簡略化させるのか?
ですが、Promiseには独自のPromiseというオブジェクト(部品)が定義されています。

このPromiseオブジェクトを使って、コールバック関数(他の関数の引数として使用し、特定のタイミングで実行できる関数)を簡略化し、コードをすっきりさせます。

ちなみにPromiseオブジェクトには状態が定義されていて、処理の状態によって以下の3つの状態に定義されるんですが、

  • penndhing : 初期状態。処理が成功も失敗もしていない状態
  • fulfilled : 処理が成功・完了した状態
  • rejected : 処理が失敗した状態

この状態によって、以前は処理の成功・失敗判定を分けて書いていたコードが、Promiseオブジェクトを通して一つにまとめることができるようになったのです。

MDNのPromise記事を参考にすると、以下のような感じ。

function success(result){
	console.log("成功" + result);
}
function fail(error){
	console.log("失敗" + fail);
}

doSome(success, fail);

//Promiseで書いた場合
let promise = doSome();

promise.then(success, fail);

Promiseの状態によって処理の結果が管理でき、いたずらに分ける必要がなくなったので、コードがすっきりですね。

さらにPromiseオブジェクトは共有することも出来、同じオブジェクトで紐つなぎに結果を変更していく事ができます。(Promiseチェーンというらしい)

//promiseチェーン
	const promise = doSome();

	const promise2 = promise.then(success, fail);
	//promise2でdoSomeの完了結果を表し、更に自分が持つ処理の結果も表す

上記のPromise2という変数は上の変数にある処理(doSomeってやつ)の完了を表すほか、自分の所にある処理(promise.then)の完了も表すことができます。これらの特性がコードを簡略化させるのに一役買っていて、非同期処理を扱う際に便利になるといわれるゆえん。

さて、なんとなくPromiseの基本を学んだので、さっそく使ってみましょう。

Promiseの基本構文

まずはPromiseの基本構文。新しいプロミスオブジェクトを作成するためには以下のようにnewを使って作成します。

new Promise(function(resolve, reject){...} );

中のfunctionはexecutor関数言うらしいです。直訳見たら「執行者」とかって意味だったので、実行する関数に命令する人って感じなんですかね。

そしてそのfunctionの引数に指定されているresolve、rejectという2つの関数がPromiseオブジェクトが出来た時に実行される関数になります。
先に触れたPromiseオブジェクトの状態(初期・成功・失敗)を、この2つの関数で判定していくわけです。

次はこの基本構文に設定する、処理結果を返すためのメソッドを紹介します。

Promiseのメソッド

このメソッドは、値を返すコードと思ってもらうと理解しやすいかもしれません。
なんか全部理解しようとすると頭がほうける感じがした(自分だけかもしれません 汗)ので。

さっきの基本構文の中に下記のメソッドを設定すると、内容に沿った値やオブジェクトが結果として返ってくる。ってだけです。

難しく考えるのはやめましょう。その方が幸せです。

基本メソッド一覧

 

Promise.all(iterable)
繰り返されたPromiseが全て成功の場合またはいずれかが失敗した段階の状態を返す。
全て成功の場合は、定義された順に配列で値を返す。失敗した場合は、失敗した時の理由を値で返す。
複数のPromiseをまとめる時に使うメソッド。
Promise.race(iterable)
繰り返されたPromiseのうち、最初に成功・失敗したPromiseを値で返す。
Promise.reject(reason)
reasonを与えられて失敗となったPromiseオブジェクトを返す
Promise.resolve(value)
valueを与えられて成功となったPromiseオブジェクトを返す。

MDNの説明文を見ていて個人的に思った部分は、Promise、Promise同じ言葉が何回も出てくるので頭がこんがらがる感じ。
MDNの説明文にはPromiseがPromiseを返すとか書いてあるんですけど、とりあえず整理しやすいように、上のメソッドの説明はシンプルに抜粋してます。

続いてpwaのチュートリアルにも登場する.thenとか.catch

Promiseプロトタイプメソッド

プロトタイプメソッドは、Promiseの中身に状態を付与するメソッドです。
基本メソッドでは、実行する関数にPromiseを返す形でしたが、こちらはPromise自体に中身を付与していく感じ。

 

Promise.catch(onRejected)
Promiseに失敗ハンドラコールバックを付加する。
Promise.then(onFulfilled, onRejected)
成功ハンドラと失敗ハンドラを付加。成功か失敗か、ハンドラの戻り値によって結果が出ている新しいPromiseを返す。

うーん、ハンドラコールバックって何やねん?
イベントハンドラとコールバック関数ってことでよいのかな?

promiseオブジェクトに関数を入れて指定タイミングで呼び出すってことなら、おそらく上記の解釈で良いはず、、、
(間違ってたら教えてください、、)

次回は実際にPromiseコードを書いていきます

とりあえずコレで基礎(ホントにホントの基礎)部分はおさえたと思いますので、次は実際にコードを書いてみたい。

ですが、予想以上に長くなったので、今回を前編とし、次回にコードを書いて実践してみたいと思います。
それではまた!

javascript Promiseの勉強 後編はこちらから

javascriptカテゴリの最新記事