WEBVTT

1
00:00:00.000 --> 00:00:00.976
こんにちは。

2
00:00:00.976 --> 00:00:04.555
ジャバスクリプト入門、実践連載の第五回です。

3
00:00:04.555 --> 00:00:06.996
今回のテーマは非同期処理です。

4
00:00:06.996 --> 00:00:11.714
通信やファイルの読み込みは、終わるまでに時間がかかります。

5
00:00:11.714 --> 00:00:16.757
その間、画面や次の処理を止めないための仕組みが非同期処理です。

6
00:00:16.757 --> 00:00:22.045
中心になるのは、将来の結果を表すプロミスと、それを読みやすく書くアシンクとアウェイト、

7
00:00:22.045 --> 00:00:27.332
そしてサーバーからデータを取るフェッチです。

8
00:00:27.332 --> 00:00:31.806
さらに、失敗したときの備えとして、エイチティーティーピーエラーの確認、データの検証、

9
00:00:31.806 --> 00:00:36.280
タイムアウトまで扱います。

10
00:00:36.280 --> 00:00:41.812
小さなジェイソンファイルを読み込む例で、全体の流れを確かめましょう。

11
00:00:41.812 --> 00:00:44.966
まず、なぜ非同期が必要なのかを考えます。

12
00:00:44.966 --> 00:00:51.590
ネットワーク越しにデータを取ると、返事が来るまで数百ミリ秒、ときには数秒かかります。

13
00:00:51.590 --> 00:00:58.687
もしその間、プログラム全体が止まってしまったら、画面は固まり、ほかの操作も受け付けません。

14
00:00:58.687 --> 00:01:07.361
そこでジャバスクリプトでは、時間のかかる処理を始めたら、完了したときに結果を受け取る約束だけを先にもらいます。

15
00:01:07.361 --> 00:01:11.303
待っている間もエンジンはほかの仕事を進められます。

16
00:01:11.303 --> 00:01:16.508
アウェイトで待つ、という書き方も、全体を止める命令ではありません。

17
00:01:16.508 --> 00:01:22.658
特定の関数の続きを、結果が届いてから再開する、という意味だと理解してください。

18
00:01:22.658 --> 00:01:29.755
天気や地図のように、最新の情報を外部から取る場面では、この考え方がそのまま土台になります。

19
00:01:29.755 --> 00:01:34.251
プロミスは、将来の成功または失敗を表すオブジェクトです。

20
00:01:34.251 --> 00:01:40.674
処理が終われば成功として値を渡し、途中で問題が起きれば失敗として理由を渡します。

21
00:01:40.674 --> 00:01:44.528
身近な例でいえば、注文の受付票のようなものです。

22
00:01:44.528 --> 00:01:51.111
注文した瞬間に料理は出てきませんが、番号札があるので、できあがったら受け取れます。

23
00:01:51.111 --> 00:01:55.446
この回では、タイマーを使った小さなプロミスを作ります。

24
00:01:55.446 --> 00:02:02.993
指定したミリ秒が経ったら完了する、という単純なもので、プロミスの動きを確かめる土台になります。

25
00:02:02.993 --> 00:02:09.095
プロミスは結果そのものではなく、結果への約束だ、という点を押さえてください。

26
00:02:09.095 --> 00:02:14.491
アシンクとアウェイトは、プロミスを分かりやすく書くための文法です。

27
00:02:14.491 --> 00:02:20.542
関数にアシンクを付けると、その関数は自動的にプロミスを返すようになります。

28
00:02:20.542 --> 00:02:27.901
中でアウェイトを使うと、その処理の完了を待って、結果の値を普通の変数のように受け取れます。

29
00:02:27.901 --> 00:02:29.700
利点は読みやすさです。

30
00:02:29.700 --> 00:02:37.385
成功したら次へ、といったつなぎ方を何段も重ねなくても、上から下へ順番に読めるコードになります。

31
00:02:37.385 --> 00:02:43.926
先ほどのタイマーをアウェイトで待ち、完了したらメッセージを作る関数を用意します。

32
00:02:43.926 --> 00:02:49.977
二つのメッセージを並行に作って結果を出す流れが、この回の最初の完成形です。

33
00:02:49.977 --> 00:02:53.472
複数の非同期処理をまとめて待つ方法が二つあります。

34
00:02:53.472 --> 00:02:57.946
プロミスオールは、すべて成功したら入力した順番で結果を返します。

35
00:02:57.946 --> 00:03:01.720
ただし、一つでも失敗すると全体が失敗として扱われます。

36
00:03:01.720 --> 00:03:06.334
しかも、すでに始まったほかの処理が自動で止まるわけではありません。

37
00:03:06.334 --> 00:03:13.044
もう一つのオールセトルドは、成功も失敗もすべて終わるまで待ち、それぞれの成否を記録して返します。

38
00:03:13.044 --> 00:03:17.238
一部が失敗しても、ほかの結果を確認したい場面に向いています。

39
00:03:17.238 --> 00:03:20.593
速さや厳しさを取りたいならオール、記録を漏らしたくないならオールセトルド、

40
00:03:20.593 --> 00:03:23.949
と使い分けてください。

41
00:03:23.949 --> 00:03:32.197
どちらを選ぶかは、失敗したときに全体を止めたいのか、それとも結果を残して後で対処したいのかで決めると分かりやすいです。

42
00:03:32.197 --> 00:03:36.040
次はフェッチで、サーバーからジェイソンを取得します。

43
00:03:36.040 --> 00:03:39.440
ここで初心者がつまずきやすい注意点があります。

44
00:03:39.440 --> 00:03:44.983
フェッチは、ページが見つからない四百四のようなエイチティーティーピーエラーでも、

45
00:03:44.983 --> 00:03:50.526
通常は失敗扱いにならず、レスポンスという応答のオブジェクトを返します。

46
00:03:50.526 --> 00:03:57.326
そのため、まずレスポンスのオーケーという項目を確認し、成功でなければ自分でエラーを投げます。

47
00:03:57.326 --> 00:04:00.430
その後に、本文をジェイソンとして読みます。

48
00:04:00.430 --> 00:04:03.977
通信できたことと、内容が正しいことは別問題です。

49
00:04:03.977 --> 00:04:08.560
順番に確認する関門を置くことが、確実な通信の第一歩になります。

50
00:04:08.560 --> 00:04:16.985
実際に動かすときは、ローカルに小さなサーバーを立てて、そこに置いたジェイソンファイルを読み込む形で試すと安全です。

51
00:04:16.985 --> 00:04:21.193
データを読み込めても、それで終わりではありません。

52
00:04:21.193 --> 00:04:28.093
ジェイソンとして解析できても、必要な形になっているかは別に確かめる必要があります。

53
00:04:28.093 --> 00:04:37.518
この例では、本の一覧を想定し、全体が配列であること、各要素のアイディーとタイトルが文字列であることを確認します。

54
00:04:37.518 --> 00:04:41.725
形が違えば、タイプエラーとして早めに失敗させます。

55
00:04:41.725 --> 00:04:47.111
そして、必要な項目だけを取り出した新しいオブジェクトを作ります。

56
00:04:47.111 --> 00:04:52.665
余分な項目や想定外の型を、後段の処理へ持ち込まないための工夫です。

57
00:04:52.665 --> 00:04:56.199
外部から来たデータは、まず疑って検証する。

58
00:04:56.199 --> 00:05:00.407
この習慣が、原因の分かりにくい不具合を減らします。

59
00:05:00.407 --> 00:05:04.791
通信がいつまでも終わらない場合に備え、中断の仕組みも用意します。

60
00:05:04.791 --> 00:05:08.900
アボートコントローラーは、中断を知らせる信号を作る道具です。

61
00:05:08.900 --> 00:05:14.380
その信号をフェッチへ渡しておくと、アボートを呼んだときに待ち受けを止められます。

62
00:05:14.380 --> 00:05:19.038
この例では五秒のタイマーを仕掛け、時間内に終わらなければ中断します。

63
00:05:19.038 --> 00:05:21.230
後始末はファイナリーで行います。

64
00:05:21.230 --> 00:05:24.929
成功でも失敗でも中断でも、最後にタイマーを解除します。

65
00:05:24.929 --> 00:05:28.353
なお、この中断は、自分の側の待機を止めるものです。

66
00:05:28.353 --> 00:05:34.107
サーバー側で進んだ処理そのものを取り消す保証はない、という点も覚えておいてください。

67
00:05:34.107 --> 00:05:37.950
エラー処理では、どんな失敗が起きたかを分けて考えることが大切です。

68
00:05:37.950 --> 00:05:40.978
この例で起こりうる失敗は、少なくとも四種類あります。

69
00:05:40.978 --> 00:05:45.286
アドレスが違って起きるエイチティーティーピーエラー、本文が壊れていて起きる解析エラー、

70
00:05:45.286 --> 00:05:49.595
形が違うことで起きる検証エラー、そして時間切れによる中断です。

71
00:05:49.595 --> 00:05:53.846
トライとキャッチで失敗をまとめて受け取りつつ、中断かどうかは信号の状態で見分け、

72
00:05:53.846 --> 00:05:58.096
利用者には待ち時間の上限に達した、といった分かる言葉で知らせます。

73
00:05:58.096 --> 00:06:03.569
失敗の種類ごとに次の行動が変わるので、一つのエラーメッセージに押し込めないことがポイントです。

74
00:06:03.569 --> 00:06:10.207
失敗を種類ごとにメモしておくと、練習でわざとエラーを起こしたときにも、どこで止まったのかをすぐに追いかけられます。

75
00:06:10.207 --> 00:06:12.598
よくある間違いも二つ押さえます。

76
00:06:12.598 --> 00:06:18.873
一つ目は、フォーイーチの中でアシンク関数を使い、外側で待てると思ってしまうことです。

77
00:06:18.873 --> 00:06:23.803
フォーイーチは、コールバックが返したプロミスをまとめて待ちません。

78
00:06:23.803 --> 00:06:32.021
順番に処理したいならフォーオブとアウェイト、同時に進めたいならマップでプロミスの配列を作ってオールへ渡します。

79
00:06:32.021 --> 00:06:35.308
二つ目は、大量の処理を一度に始めることです。

80
00:06:35.308 --> 00:06:43.376
オールへ渡す前に関数を呼んだ時点で処理は始まっているため、数万件を同時に動かすと接続やメモリーを圧迫します。

81
00:06:43.376 --> 00:06:46.813
同時に動かす数を絞る工夫は、最終回で扱います。

82
00:06:46.813 --> 00:06:47.675
まとめです。

83
00:06:47.675 --> 00:06:52.323
今回は、プロミスという約束、アシンクとアウェイトによる読みやすい書き方、

84
00:06:52.323 --> 00:06:56.970
フェッチでの取得、オーケーの確認とデータ検証、アボートコントローラーによる中断、

85
00:06:56.970 --> 00:07:01.617
そしてファイナリーでの後始末を学びました。

86
00:07:01.617 --> 00:07:04.923
練習として、失敗をわざと起こしてみてください。

87
00:07:04.923 --> 00:07:10.241
存在しないファイルを指定してエイチティーティーピーエラーを、ジェイソンを壊して解析エラーを、

88
00:07:10.241 --> 00:07:15.559
タイトルを数値に変えて検証エラーを、それぞれ確かめます。

89
00:07:15.559 --> 00:07:21.740
なおブラウザーから別のサイトへ通信するときは、コルスと呼ばれる制限にも注意が必要です。

90
00:07:21.740 --> 00:07:26.052
次回はクラスで、状態と処理をひとまとめにする方法を学びます。

91
00:07:26.052 --> 00:07:27.920
これで第五回を終わります。

92
00:07:27.920 --> 00:07:33.382
一つずつ試して、成功したときと失敗したときの表示の違いを比べてみてください。

93
00:07:33.382 --> 00:07:36.113
その違いこそが、今回の学習の成果です。
