Slide 1

Slide 1 text

Promise 2018/06/15 第9回 TG社フロントエンド勉強会 Tatsuya Nakano(howdy39)

Slide 2

Slide 2 text

Promise ● PromiseはJavaScriptのオブジェクト ● 処理が終わったら教えるよという 約束 ● 非同期処理を統一されたインターフェースで書ける ● コールバック地獄の回避につかえる ● ES2015で追加 https://caniuse.com/#search=promise IE以外は使える・・・ →IEに対応するなら 要 Polyfill (es6-promise etc

Slide 3

Slide 3 text

Promiseの基本

Slide 4

Slide 4 text

Promiseの基本 // Promiseオブジェクトを作成 const promise = new Promise((resolve, reject) => { // 何らかの処理(非同期処理) if (解決時) { resolve('解決'); } else { reject(new Error('棄却')); } });

Slide 5

Slide 5 text

Promiseの基本 const promise = new Promise((resolve, reject) => { /* 省略 */ }); // Promiseオブジェクトの結果により処理を実行 promise .then(value => { console.log('then', value); // resolve()が呼ばれた場合 }) .catch(value => { console.log('catch', value); // reject()が呼ばれた場合 });

Slide 6

Slide 6 text

Promiseオブジェクトの作り方 その1

Slide 7

Slide 7 text

new Promise(fn) const promise = new Promise((resolve, reject) => { // 何らかの処理 });

Slide 8

Slide 8 text

Promiseオブジェクトの作り方 その2

Slide 9

Slide 9 text

Promise.resolve() Promise.resolve()は解決したPromiseオブジェクトを返す ※次の1と2は同じ 1. const promise = Promise.resolve('howdy39'); 2. const promise = new Promise((resolve) => { resolve('howdy39') });

Slide 10

Slide 10 text

Promise.reject() Promise.reject()は棄却したPromiseオブジェクトを返す ※次の1と2は同じ 1. const promise = Promise.reject('howdy39'); 2. const promise = new Promise((resolve, reject) => { reject('howdy39') });

Slide 11

Slide 11 text

Promiseオブジェクトの作り方 その3

Slide 12

Slide 12 text

Fetch 等のPromiseを返す関数など const promise = fetch('https://api.github.com/orgs/topgate');

Slide 13

Slide 13 text

Promiseオブジェクトが持つメソッド

Slide 14

Slide 14 text

Promiseオブジェクトが持つ2つのメソッド Promise#then(onFulfilled, onRejected) 解決時はonFulfilledハンドラの処理が呼ばれる 棄却時はonRejectedハンドラの処理が呼ばれる Promise#catch(onRejected) Promise#then(undefined, onRejected) のシンタックスシュ ガー then()もcatch()、どちらもPromiseオブジェクトを返す

Slide 15

Slide 15 text

メソッドチェーン

Slide 16

Slide 16 text

メソッドチェーン Promiseはthenメソッドを使ってメソッドチェーンにできる ※thenメソッドの戻りがPromiseオブジェクトだから Promise.resolve() // 解決したPromise .then(() => console.log('aaa')) .then(() => console.log('bbb')) .then(() => console.log('ccc'));

Slide 17

Slide 17 text

次のPromiseに値を渡す(値をreturn) Promise.resolve() .then(() => { console.log('aaa'); return 'howdy39'; // 値をreturnすればOK }) .then((value) => console.log('bbb', value)) .then(() => console.log('ccc'));

Slide 18

Slide 18 text

次の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'));

Slide 19

Slide 19 text

次の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));

Slide 20

Slide 20 text

棄却時のハンドリング

Slide 21

Slide 21 text

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'));

Slide 22

Slide 22 text

複数のPromiseを扱う

Slide 23

Slide 23 text

Promise.all()

Slide 24

Slide 24 text

Promise.all() Promiseの配列を指定すると並列に実行される すべてのPromiseが解決するとthenの処理が呼ばれる いずれかのPromiseが棄却するとcatchの処理が呼ばれる Promise.all([Promise1, Promise2, Promise3]);

Slide 25

Slide 25 text

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) // 棄却時の処理; );

Slide 26

Slide 26 text

Promise.all()で複数の値を受け取る

Slide 27

Slide 27 text

分割代入を使うと楽 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); });

Slide 28

Slide 28 text

いずれかのPromiseが棄却

Slide 29

Slide 29 text

Promise.race()

Slide 30

Slide 30 text

Promise.race() Promiseの配列を指定すると並列に実行される いずれかのPromiseが解決するとthenの処理が呼ばれる いずれかのPromiseが棄却するとcatchの処理が呼ばれる Promise.race([Promise1, Promise2, Promise3]); 使う機会はあんまりなさそう

Slide 31

Slide 31 text

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) // 棄却時の処理; );

Slide 32

Slide 32 text

おまけ

Slide 33

Slide 33 text

Promise#finally() Promiseオブジェクトにはthenとcatchの他にfinallyも存在 ES 2018 で実装 http://kangax.github.io/compat-table/es2016plus/#test-Promis e.prototype.finally

Slide 34

Slide 34 text

finallyは解決/棄却に関係なく呼ばれる Promise.resolve() .then(() => Promise.reject(new Error('my error'))) .catch(error => console.log('error', error)) .finally(() => console.log('finally222'));

Slide 35

Slide 35 text

まとめ 1. Promiseを使うと非同期処理がきれいに書ける 2. fetch はPromiseを返す 3. Promise#all()で非同期処理をまとめてかける

Slide 36

Slide 36 text

参考 JavaScript Promiseの本 http://azu.github.io/promises-book Promise | MDN https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise.prototype | MDN https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype 今更だけどPromise入門 https://qiita.com/koki_cheese/items/c559da338a3d307c9d88 JavaScript の Promise https://developers.google.com/web/fundamentals/primers/promises