CSS
JavaScript
CSS3

Promise - 見た目もスッキリ!順番通りに処理する方法

promise.gif

                               ※脚色を含みます。

はじめに

この記事では、Promiseを使って、狙い通りに処理を順番に実行する方法を紹介します。
JavascriptでFirebaseを使用する際などに、何かと必要になるのが、このPromiseです。

Javascriptの特性

Javascriptは非同期処理言語

Javascriptは非同期処理の言語です。
ソースコードの記述通り、1行目から最終行目まで順に処理が開始されますが、
各処理の間に、「完了 → 開始」の関係があるわけではありません。
そのため、前の処理が時間のかかるものであれば、後に書いた処理の方が先に完了してしまうことがあります。

やっかいな、と思われるかもしれませんが、この仕組みが高速レスポンスを実現している面もありますので、やむを得ません。

Promiseの出番

しかし、プログラマにとって、順番を決めて動いてもらわないと困るシーンはたくさんあります。
時間のかかる処理の代表格が、データベース操作などのサバー処理です。
「データベースには確かに値が登録されていているのに、ページに表示されない! なんで??」といった問題は、Promiseを使うことで解決する可能性があります。

Promiseの使い方

Promiseにはいくつかの処理をまとめて行う、並列処理もありますが、ここでは直列処理を紹介します。
その名の通り、順番に処理させる書き方です。

promise.js
        Promise.resolve()
        .then( () => 処理1 )
        .then( () => 処理2 )
        .then( () => 処理3 );

このように、Promise.resolve()の後に、.then()を数珠のように必要な分だけつなぎ、
最後にセミコロンを記述します。
このように書けば、「処理1の完了 → 処理2の開始・・・」と処理3の完了まで順番通り実行されます。

「処理2と処理3の間に2秒間置きたい」場合には、次のように書くことで実現できます。

promise.js
        const wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
        Promise.resolve()
        .then( () => 処理1 )
        .then( () => 処理2 )
        .then( () => wait(2000) )
        .then( () => 処理3 );

Promiseオブジェクトを返す関数を作成し、wait(ミリ秒)で時間を置けるようにしています。
※const wait〜は関数式です。シンプルに記述することができます。
CSSアニメーション処理を途中で挟むために、classをaddしてremoveするときにも重宝します。

また、途中でif文を使用したい場合は次のように{}で囲みます。

promise.js
     Promise.resolve()
            .then( () => 処理1 )
            .then( () => {if( ~ ) {
                                  処理2
                                 }
                         })
            .then( () => 処理3 );

{}で囲むことで、if文に限らず、複数の処理を書き込むことが可能になります。

さいごに

Promiseを使いこなせるようになると、Javascriptでの表現の幅を広げることができます。
並列処理をはじめ、ここで紹介できていない方法もたくさんあり、私も引き続き学んでいこうと思います。

この記事ではPromiseの仕組み等について詳細な解説はしていません。
下記のサイト、記事が分かりやすくまとめられていると思いましたので紹介します。

setTimeoutはダサいぞ。JavaScript Promiseを使って処理を順番に実行しよう
new PromiseとPromise.resolveの違い

参考:
Javascript初心者がsetTimeoutを使ったとき行き詰ったこと