Promise2018/06/15 第9回 TG社フロントエンド勉強会Tatsuya Nakano(howdy39)
View Slide
Promise● PromiseはJavaScriptのオブジェクト● 処理が終わったら教えるよという 約束● 非同期処理を統一されたインターフェースで書ける● コールバック地獄の回避につかえる● ES2015で追加https://caniuse.com/#search=promiseIE以外は使える・・・→IEに対応するなら 要 Polyfill (es6-promise etc
Promiseの基本
Promiseの基本// Promiseオブジェクトを作成const promise = new Promise((resolve, reject) => {// 何らかの処理(非同期処理)if (解決時) {resolve('解決');} else {reject(new Error('棄却'));}});
Promiseの基本const promise = new Promise((resolve, reject) => {/* 省略 */});// Promiseオブジェクトの結果により処理を実行promise.then(value => {console.log('then', value); // resolve()が呼ばれた場合}).catch(value => {console.log('catch', value); // reject()が呼ばれた場合});
Promiseオブジェクトの作り方その1
new Promise(fn)const promise = new Promise((resolve, reject) => {// 何らかの処理});
Promiseオブジェクトの作り方その2
Promise.resolve()Promise.resolve()は解決したPromiseオブジェクトを返す※次の1と2は同じ1. const promise = Promise.resolve('howdy39');2. const promise = new Promise((resolve) => {resolve('howdy39')});
Promise.reject()Promise.reject()は棄却したPromiseオブジェクトを返す※次の1と2は同じ1. const promise = Promise.reject('howdy39');2. const promise = new Promise((resolve, reject) => {reject('howdy39')});
Promiseオブジェクトの作り方その3
Fetch 等のPromiseを返す関数などconst promise = fetch('https://api.github.com/orgs/topgate');
Promiseオブジェクトが持つメソッド
Promiseオブジェクトが持つ2つのメソッドPromise#then(onFulfilled, onRejected)解決時はonFulfilledハンドラの処理が呼ばれる棄却時はonRejectedハンドラの処理が呼ばれるPromise#catch(onRejected)Promise#then(undefined, onRejected) のシンタックスシュガーthen()もcatch()、どちらもPromiseオブジェクトを返す
メソッドチェーン
メソッドチェーンPromiseはthenメソッドを使ってメソッドチェーンにできる※thenメソッドの戻りがPromiseオブジェクトだからPromise.resolve() // 解決したPromise.then(() => console.log('aaa')).then(() => console.log('bbb')).then(() => console.log('ccc'));
次のPromiseに値を渡す(値をreturn)Promise.resolve().then(() => {console.log('aaa');return 'howdy39'; // 値をreturnすればOK}).then((value) => console.log('bbb', value)).then(() => console.log('ccc'));
次のPromiseに値を渡す(Promiseをreturn)Promise.resolve().then(() => {console.log('aaa');return Promise.resolve('howdy39'); // Promiseをreturn}).then((value) => console.log('bbb', value)).then(() => console.log('ccc'));
次のPromiseに値を渡す(fetchをreturn)Promise.resolve().then(() => {console.log('aaa');return fetch('https://api.github.com/orgs/topgate');}).then(response => {console.log('bbb');return response.json(); // Response#json()はPromiseを返す}).then(json => console.log('ccc', json));
棄却時のハンドリング
catch()で棄却をハンドリングPromiseはcatchメソッドを使って棄却時のハンドリングをするPromise.reject(new Error('my error')) // 棄却したPromise.then(() => console.log('aaa')).then(() => console.log('bbb')).catch((error) => console.log('ccc', error)).then(() => console.log('ddd'));
複数のPromiseを扱う
Promise.all()
Promise.all()Promiseの配列を指定すると並列に実行されるすべてのPromiseが解決するとthenの処理が呼ばれるいずれかのPromiseが棄却するとcatchの処理が呼ばれるPromise.all([Promise1, Promise2, Promise3]);
Promise.all([new Promise(resolve => {console.log('aaa');resolve();}),new Promise(resolve => {console.log('bbb');resolve();}),]).then(() => console.log('ccc'), // 解決時の処理).catch((error) => console.log('ddd', error) // 棄却時の処理;);
Promise.all()で複数の値を受け取る
分割代入を使うと楽Promise.all([Promise.resolve('aaa'),Promise.resolve('bbb'),Promise.resolve('ccc'),]).then(values => {const [a, b, c] = values;console.log('a', a);console.log('b', b);console.log('c', c);});
いずれかのPromiseが棄却
Promise.race()
Promise.race()Promiseの配列を指定すると並列に実行されるいずれかのPromiseが解決するとthenの処理が呼ばれるいずれかのPromiseが棄却するとcatchの処理が呼ばれるPromise.race([Promise1, Promise2, Promise3]);使う機会はあんまりなさそう
Promise.race([new Promise(resolve => {console.log('aaa');resolve();}),new Promise(resolve => {console.log('bbb');reject(new Error('bbb error'));}),]).then(() => console.log('ccc'), // 解決時の処理).catch((error) => console.log('ddd', error) // 棄却時の処理;);
おまけ
Promise#finally()Promiseオブジェクトにはthenとcatchの他にfinallyも存在ES 2018 で実装http://kangax.github.io/compat-table/es2016plus/#test-Promise.prototype.finally
finallyは解決/棄却に関係なく呼ばれるPromise.resolve().then(() => Promise.reject(new Error('my error'))).catch(error => console.log('error', error)).finally(() => console.log('finally222'));
まとめ1. Promiseを使うと非同期処理がきれいに書ける2. fetch はPromiseを返す3. Promise#all()で非同期処理をまとめてかける
参考JavaScript Promiseの本http://azu.github.io/promises-bookPromise | MDNhttps://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/PromisePromise.prototype | MDNhttps://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype今更だけどPromise入門https://qiita.com/koki_cheese/items/c559da338a3d307c9d88JavaScript の Promisehttps://developers.google.com/web/fundamentals/primers/promises