JavaScriptで役立つPromiseテンプレ（WebDevTips#1）


こんにちは，くるみです．
これまでは主にpythonに触れてきましたが，最近Javascriptを勉強し始めたので，Webエンジニアを目指す方々へのtipsとして記事を書いていきたいと思います．


# Promiseとは
Promiseとは，一体なんでしょう？
Googleで「javascript promise」と検索してみると...

##### Promise                                
>Promise オブジェクトは非同期処理の最終的な完了処理 (もしくは失敗) およびその結果の値を表現します。

という説明が出てきます．

「非同期処理ってなんだ？」と思った方，こちらもGoogleで「非同期処理とは」と検索すると...

##### 非同期処理
>非同期処理とは、一つのタスクを実行中であっても他のタスクを実行できる実行方式をいいます。 非同期処理をうまく実装することで、ユーザーはアプリケーションの処理待ちを気にすることなくアクセスすることができるため、ユーザビリティを考えるうえで重要な要素になります。

これをみると，なんとなく
#####Promiseは複数のタスクを同時に処理するときに役立つ関数
ということが分かりますね．


# コードの作成
それでは実際にコードを書いて動かしてみましょう！
今回はエディタとしてVisual Studio Code（VSCode）を使用し，terminalで実行していこうと思います．

実行環境は以下の通りです．

##### 実行環境
|macOS|Big Sur 11.5.2|
|:--|:--|
|Node.js|v16.7.0|

同様の実行環境を作成したい場合には，
>① VSCodeのインストール　（公式ホームページから）
>② Homebrewのインストール（公式ホームページからコードをコピー）
>③ nodebrewのインストール（terminal上で）
>③ nodebrewの有効化（terminal上で）
>④ VSCodeで「control+shift+@」によりterminalの起動

により，準備完了です．
記事の最後に参考文献を記載しておきますので，そちらから環境構築してみてください！

##### サンプルコード全体
```script1.js
//こちらはコメントです．
//letでローカル変数を定義

let p = new Promise((resolve, reject) => {
  let a = 1+1
  if( a == 2){
    resolve('Success')
  }else{
    reject('Failed')
  }
})

p.then((message)=>{
  console.log('This is in the then '+ message)
}).catch((message)=> {
  console.log('This is in the catch ' + message)
})
```

こちらのコードをもとにPromiseの仕様を説明していきます．

Promiseは，２つの引数__resolve__と__reject__を持ちます．
ここでは，pという変数にPromiseという関数が定義されました．
この関数の中では，aという変数が2であるときに__Success__と返し，それ以外のときには__Failed__と返すようになっています．

このように，パスした場合には__resolve__が適用され，エラーが起きた場合には__reject__が適用されるのです．

Webアプリを開発する上で，エラーが起きるのは日常茶飯事なので，「どの関数がきちんとパスして，どの関数でエラーが起きているのか」を知ることは非常に大切です．

サンプルコードの__.then__と__.catch__について説明します．

__.then__はPromiseが成功した場合の返り値を受け取ります．
__.catch__はPromiseが失敗した，エラーが起きた場合の返り値を受け取ります．

以上を実行すると（terminal上でnode script1.jsと打つと），
>This is in the then Success

と返ってきます．（a=1+2と変更すると，This is in the catch Failedとなります）

# タスクの直列化と並列化
ここまで，Promiseの基本的な文法を学習してきました．
ここからは，Promiseの真骨頂であるタスクの直列化，並列化についてお話ししていきます．

まずは，サンプルコードを見てみましょう！

##### サンプルコード全体
```script2.js
//こちらはコメントです．
//constで定数を定義

const recordVideoone = new Promise((resolve,reject)=>{
  console.log('Video 1');
  resolve('Video 1')
})

const recordVideotwo = new Promise((resolve,reject)=>{
  console.log('Video 2');
  resolve('Video 2')
})

const recordVideothree = new Promise((resolve,reject)=>{
  console.log('Video 3');
  resolve('Video 3')
})

const recordVideofour = new Promise((resolve,reject)=>{
  console.log('Video 4');
  resolve('Video 4')
})

//並列処理
Promise.all([
  recordVideoone,
  recordVideotwo,
  recordVideothree,
  recordVideofour
]).then((messages) =>{
  console.log(messages)
})

//直列処理
Promise.resolve()
    .then(recordVideoone)
    .then(recordVideotwo)
    .then(recordVideothree)
    .then(recordVideofour);
```
javascriptでは，上から順番に処理されるわけではなく，同時にタスクが処理されてしまうので，本当は「１，２，３，４」の順番で実行したいのに，「２，４，１，３」の順番で処理されてしまうということが起こり得ます．

そこで，上から順番に処理してもらうために，直列処理の__Promise.resolve__を使います．

__Promise.resolve__とすると，上から順番に処理されます．
__Promise.all__とすると，[]の中に含まれている関数を同時に並列処理してくれます．

これらを組み合わせることで，ユーザビリティの高いアプリケーションを開発することが可能になります．

次回の記事はこちら▼

https://qiita.com/cocoa_folio/items/666d331d52aa9669d358

次回はasync/awaitについて説明していきます！

#####参考文献：
MacにNode.jsをインストール：https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09
JavaScript Promises In 10 Minutes：https://www.youtube.com/watch?v=DHvZLI7Db8E