Slide 1

Slide 1 text

1時間1時間半で克服する JavaScriptの非同期処理 〜Promise, async/await〜

Slide 2

Slide 2 text

自己紹介 - 名前: 阿部 真之 - 仕事: 株式会社ゆめみ でAndroidエンジニアしてます - 最近はサーバサイド Kotlinの仕事も始めました - 趣味 - コーヒー、ビール、アニメ、ゲーム、読書、 etc… - Twitter: @marchin_1989

Slide 3

Slide 3 text

アジェンダ - 同期処理、非同期処理とは - コールバックによる非同期処理 - Promise - async/await - まとめ

Slide 4

Slide 4 text

対象者 - JavaScriptでプログラミングしたことがある方 - Promiseやasync/awaitによる非同期処理があまり理解できていないと感じる方

Slide 5

Slide 5 text

よくあるつまずきポイント - なぜか処理が呼び出されなかったり、期待する順番で動作させることができない - いつ非同期処理が必要になるのかわからない - いつawaitをつけるべき?

Slide 6

Slide 6 text

同期処理、非同期処理とは?

Slide 7

Slide 7 text

同期処理 処理Aから順番に実行される。 次の処理(処理B)は、前の処理(処理 A)が終わるまで実行されない。

Slide 8

Slide 8 text

同期処理 非同期処理 前の処理(処理B)が完了する のを待たずに、次の処理 (処理 C)を実行できる。

Slide 9

Slide 9 text

なぜ非同期処理が必要なのか?

Slide 10

Slide 10 text

なぜ非同期処理が必要なのか?(同期処理だと困ること) - 同期処理だと、実行中の処理が終わるまで、次の処理を実行できない。 - 長時間かかるような処理を実行すると、次の処理をすぐ実行したくてもできない - 例1: Appサーバで、HTTPリクエストごとにデータベースにアクセス (I/O処理)し、完了待ちしてるとき に、別のHTTPリクエストを捌けない - 例2: ブラウザでAPIアクセスしている間に、ユーザがボタンをクリックしても反応しない

Slide 11

Slide 11 text

なぜ非同期処理が必要なのか?(非同期処理にすると) - 処理をブロックせず、次の処理を実行できる。 - 非同期処理を使って効率的に処理を実行できる。

Slide 12

Slide 12 text

JavaScriptの非同期処理

Slide 13

Slide 13 text

- JavaScriptはシングルスレッドで実行される - 普通に書いていると、同時に 1つのことしか実行できない。 (同期処理) JavaScriptの非同期処理

Slide 14

Slide 14 text

- JavaScriptはシングルスレッドで実行される - 普通に書いていると、同時に 1つのことしか実行できない。 (同期処理) - 非同期に処理されるAPI(以降、非同期API)を利用することで、非同期処理を実現 できる JavaScriptの非同期処理 非同期APIの呼び出し。 非同期に実行できるように実装 されている。

Slide 15

Slide 15 text

- タイマー - setTimeout - setInterval - I/O - fs.readFile - fetch - … JavaScriptでの非同期APIの例

Slide 16

Slide 16 text

- タイマー - setTimeout - setInterval - I/O - fs.readFile - fetch - … JavaScriptでの非同期APIの例 => コールバックを受け取るものや、Promiseを返すものなど違いがあり、 たくさんあるが、利用するときはドキュメントをしっかりみるべし

Slide 17

Slide 17 text

JavaScriptの非同期処理デモ

Slide 18

Slide 18 text

- 非同期APIは、コールバック関数を最後の引数に取り、非同期処理の終了時にコー ルバックが呼び出される - コールバックを登録しておいて、処理の完了後に呼び出される(重要) - 昔は非同期処理といえば、コールバックを使うしかなかった - コールバック地獄 - コールバックの結果を使おうとすると、ネストが深くなって読みづらくなる コールバックの非同期処理

Slide 19

Slide 19 text

- JavaScriptはシングルスレッドで実行される - 普通に書いていると、同時に 1つのことしか実行できない。 (同期処理) - 非同期に処理されるAPI(以降、非同期API)を利用することで、非同期処理を実現 できる JavaScriptの非同期処理(再掲)

Slide 20

Slide 20 text

- JavaScriptはシングルスレッドで実行される - 普通に書いていると、同時に 1つのことしか実行できない。 (同期処理) - 非同期に処理されるAPI(以降、非同期API)を利用することで、非同期処理を実現 できる JavaScriptの非同期処理(再掲) JavaScriptはシングルスレッドで、 同時に1つのことしか実行できない のに、なんで「非同期 API」というも のを呼ぶだけで非同期処理ができ る?

Slide 21

Slide 21 text

イベントループ(ざっくり)

Slide 22

Slide 22 text

イベントループ JavaScript関数の実行のされ方を みる。 まず、同期処理(非同期APIを利用し ない場合)。

Slide 23

Slide 23 text

イベントループ 呼び出された関数はコールスタック に積まれ、実行される。

Slide 24

Slide 24 text

イベントループ 実行が完了すると、ポップされる。

Slide 25

Slide 25 text

イベントループ

Slide 26

Slide 26 text

イベントループ

Slide 27

Slide 27 text

イベントループ

Slide 28

Slide 28 text

イベントループ

Slide 29

Slide 29 text

イベントループ 非同期APIの場合。 デモでみたファイル読み込みの例。

Slide 30

Slide 30 text

イベントループ

Slide 31

Slide 31 text

イベントループ

Slide 32

Slide 32 text

イベントループ

Slide 33

Slide 33 text

イベントループ JavaScriptの実行環境からオフロードされ、別スレッドで 実行される。 JavaScriptのメインスレッドとは別の場所で実行される。 ブラウザはWebAPIsが対応。

Slide 34

Slide 34 text

イベントループ 完了時のコールバック(の 参照)が渡される。

Slide 35

Slide 35 text

イベントループ 非同期APIの呼び出しは、コールス タックからすぐにポップされ、次の処 理が呼び出される。

Slide 36

Slide 36 text

イベントループ

Slide 37

Slide 37 text

イベントループ ファイルの読み込みが終わると ...

Slide 38

Slide 38 text

イベントループ メッセージキューにコール バックが追加される

Slide 39

Slide 39 text

イベントループ 【重要】コールスタックが空 になると...

Slide 40

Slide 40 text

イベントループ イベントループが、メッセージキュー にあるコールバックを、コールスタッ クに追加する

Slide 41

Slide 41 text

イベントループ ファイルの読み込み完了後のコール バックの処理が実行される

Slide 42

Slide 42 text

以上、ざっくりイベントループでした

Slide 43

Slide 43 text

Promise

Slide 44

Slide 44 text

Promiseとは - Promiseオブジェクトは、時間のかかる処理(非同期処理)を呼び出して、いつか結 果を返すと約束するもの。 - 結果は、成功 or 失敗 で返る。 - Promiseのthenメソッドを使って、非同期処理が完了し、成功が返ってきたときの処 理を、コールバック関数で登録できる。 - 失敗時の処理はcatchメソッドで登録。 - Promiseを使うことで、コールバック関数による非同期処理のネストを解消できる。 - 標準ライブラリや、サードパーティのライブラリがPromiseを返すAPIを提供している

Slide 45

Slide 45 text

Promiseのイメージ メインコード 非同期API

Slide 46

Slide 46 text

Promiseのイメージ メインコード 非同期API

Slide 47

Slide 47 text

Promiseのイメージ メインコード 非同期API

Slide 48

Slide 48 text

Promiseのイメージ メインコード 非同期API

Slide 49

Slide 49 text

Promiseのイメージ メインコード 非同期API then(成功時のコールバック ) catch(失敗時のコールバック )

Slide 50

Slide 50 text

Promiseのイメージ メインコード 非同期API

Slide 51

Slide 51 text

Promiseのデモ

Slide 52

Slide 52 text

async/await

Slide 53

Slide 53 text

async/await - async/awaitを利用することで、Promiseチェーンを使うよりすっきり書ける - ただし、Promiseの上に成り立っているので、Promiseの理解は必須 - asyncキーワード - 関数を非同期関数にするキーワード - 返り値が暗黙的にPromiseになる - awaitキーワード - async関数の中でしか使えない - Promiseオブジェクトの前につける - Promiseが「成功(resolve)」を返すまで処理が中断でき、同期的(コードの順番)にかける(ブロッキ ングするわけではない) - 成功時の結果を受け取れる( thenのコールバックの引数を返す)

Slide 54

Slide 54 text

async/awaitのデモ

Slide 55

Slide 55 text

まとめ - JavaScriptの非同期処理 - 非同期API(最後の引数にコールバックを渡す形式) - Promise - async/await - 基本はasync/awaitを使いましょう

Slide 56

Slide 56 text

参考 - Overview of Blocking vs Non-Blocking | Node.js - https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/ - The Node.js Event Loop, Timers, and process.nextTick() - https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ - 非同期 JavaScript - ウェブ開発を学ぶ | MDN - https://developer.mozilla.org/ja/docs/Learn/JavaScript/Asynchronous - What the heck is the event loop anyway? | Philip Roberts | JSConf EU - https://www.youtube.com/watch?v=8aGhZQkoFbQ - JavaScript Visualized Series' Articles - DEV Community - https://dev.to/lydiahallie/series/3341

Slide 57

Slide 57 text

ご清聴ありがとうございました!