[JavaScript General] JavaScript Promise 入門

Promise の理解が足りないので復習用にまとめておく。

[markdown]
## Promise 以前・以後

> * [Promiseで簡単!JavaScript非同期処理入門【前編】 | HTML5Experts.jp](https://html5experts.jp/takazudo/17107/)
> * [Promiseで簡単!JavaScript非同期処理入門【後編】 | HTML5Experts.jp](https://html5experts.jp/takazudo/17113/)

### Promise 前

– 非同期処理を行いたい場合、function の受け渡しをを利用して実現されてきた。
– なにかしらの処理が完了したら渡した function を実行させるという実装手法は、「コールバック」と呼ばれる。
– JavaScriptには、非同期処理をより柔軟に行える機能が求められてきた。

### Promise 後

– Promise を使えば、実行と完了に遅延がある処理をうまい具合に扱うことができる。
– Promise を利用すれば、非同期処理の書き方を統一できる。

### 各ブラウザの対応状況と Polyfill

ブラウザのサポート状況は下記で確認できる。

> * [Can I use… Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=promises)

IE は未対応なため、ブラウザポリフィルを利用して対応する。

> * [Babel: ブラウザ向けに Polyfill ライブラリを有効化する | deadwood](https://www.d-wood.com/blog/2016/04/12_7917.html)

## Promise オブジェクトの基本

> * [Promise – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)

Promise オブジェクトを利用する場合、非同期処理を関数としてまとめておく。
関数の戻り値が Promise オブジェクトになる。

“`javascript
‘use strict’;
require(‘babel-polyfill’);
/**
* @param {String} value
* @return {Promise}
*/
function asyncProcess(value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value) {
resolve(`入力値: ${value}`);
} else {
reject(‘入力値は空です。’);
}
}, 500);
});
}
“`

`resolve` 関数で成功を、`reject` 関数で失敗が通知されるのでこれを利用する。

> * [Promise.resolve() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve)
> * [Promise.reject() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject)

### then メソッドによる非同期処理の連結

`then` メソッドで Promise オブジェクトの結果を受け取る。

> [Promise.prototype.then() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then)

`then` メソッドの配下で新たな Promise オブジェクトを返すことで、複数の非同期処理を連結できる。

“`javascript
asyncProcess(‘菊次郎’)
.then(
(response) => {
console.log(response);
return asyncProcess(‘さき’);
}
)
.then(
(response) => {
console.log(response);
},
(error) => {
console.error(`エラー: ${error}`);
}
);
“`

`then` の onRejected ハンドラは、Promise オブジェクトが rejected になったときに実行される。
`then` に onRejected ハンドラが指定されていない場合、後続する `then` の onRejected ハンドラが実行される。

### catch メソッドで失敗処理をまとめて扱う

Promise には、エラー処理だけを個別に書ける `catch` メソッドが用意されている。

> [Promise.prototype.catch() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch)

前述のコードは下記に書き換えられる。

“`javascript
asyncProcess(‘菊次郎’)
.then(
(response) => {
console.log(response);
return asyncProcess(‘さき’);
}
)
.then(
(response) => {
console.log(response);
}
)
.catch(
(error) => {
console.error(`エラー: ${error}`);
}
);
“`

### 複数の非同期処理を並列実行する

`Promise.all` メソッドは、複数の非同期処理を並列に実行し、 __そのすべてが成功した場合__ に処理を実行する。

> [Promise.all() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)

“`javascript
Promise.all([
asyncProcess(‘菊次郎’),
asyncProcess(‘さき’),
asyncProcess(‘たけし’),
])
.then(
(response) => {
console.log(response);
}
)
.catch(
(error) => {
console.error(`エラー: ${error}`);
}
);
“`

`Promise.race` メソッドは、複数の非同期処理を並列に実行し、 __いずれか1つが最初に完了したところで__ 成功コールバックを呼び出す。
結果は変化する可能性がある。

> [Promise.race() – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/race)

“`javascript
Promise.race([
asyncProcess(‘菊次郎’),
asyncProcess(‘さき’),
asyncProcess(‘たけし’),
])
.then(
(response) => {
console.log(response);
}
)
.catch(
(error) => {
console.error(`エラー: ${error}`);
}
);
“`

* [training-promise/basic.es6.js at develop · DriftwoodJP/training-promise](https://github.com/DriftwoodJP/training-promise/blob/develop/src/basic.es6.js)

## 参考文献

この2つを繰り返し読みたい。

* [JavaScript Promiseの本](http://azu.github.io/promises-book/)
* [JavaScriptのPromiseオブジェクトについて調べた事 | QUARTETCOM TECH BLOG](http://tech.quartetcom.co.jp/2016/03/22/javascript-promise/)

以下の記事が、日本語で読めなくなっている。
[こちら](https://developers.google.com/web/fundamentals/getting-started/primers/promises)にリダイレクト。[日本語の原稿](https://github.com/html5j-english/www.html5rocks.com/blob/html5jeng-master/content/tutorials/es6/promises/ja/index.html)。

> * [JavaScript Promises: There and back again – HTML5 Rocks](http://www.html5rocks.com/ja/tutorials/es6/promises/)

読みづらいので後でまとめる。

> * [HTML5 Rocks の Promise 記事の抜粋 | deadwood](https://www.d-wood.com/blog/2017/02/11_8804.html)

## 補遺

* [WEB+DB PRESS Vol.87 の ECAMScript 6 (2015) 特集を読んだ | deadwood](https://www.d-wood.com/blog/2016/06/22_8191.html#5)

Node.js のサンプルコード。

* [非同期処理ってどういうこと?JavaScriptで一から学ぶ – Qiita](http://qiita.com/kiyodori/items/da434d169755cbb20447)

Generator と Promise を組み合わせることで非同期処理を同期処理のように直列に書くことができる。

* [ES6時代のJavaScript – クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2015/02/02/094607)

Promise に async / await を組み合わせて書く方法。

* [AsyncとAwait : コールバック地獄を避けるための最新のやり方、そしてその未来 | プログラミング | POSTD](http://postd.cc/async-and-await/)
[/markdown]