WEBVTT

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

2
00:00:01.114 --> 00:00:06.126
今回はジャバスクリプトのプロミス・レースを紹介します。

3
00:00:06.126 --> 00:00:16.335
これは、複数の非同期処理を同時に走らせて、その中で最初に決着した一件の結果をそのまま採用するための仕組みです。

4
00:00:16.335 --> 00:00:23.203
決着というのは、成功して終わることと、失敗して終わることの両方を含みます。

5
00:00:23.203 --> 00:00:29.515
つまりレースでは、最初に終わったのが失敗なら、全体も失敗になります。

6
00:00:29.515 --> 00:00:38.054
この動画では、書き方と引数、エニーとの違い、記事の基本例と、最初の失敗や空入力といった境界条件、

7
00:00:38.054 --> 00:00:46.592
タイムアウトへの応用、そして負けた処理が止まらない注意点まで、実行結果と一緒に学びます。

8
00:00:46.592 --> 00:00:51.233
名前の通り競争させる発想が中心になるメソッドです。

9
00:00:51.233 --> 00:01:00.700
複数の候補を順番に待つのではなく、同時に走らせて一番乗りを採用する、という発想をまず押さえてください。

10
00:01:00.700 --> 00:01:02.469
まず動作環境を確認します。

11
00:01:02.469 --> 00:01:07.436
プロミス・レースは昔からある機能で、クロームでは三十二以降、エッジでは十二以降、

12
00:01:07.436 --> 00:01:12.404
ファイアーフォックスでは二十九以降、サファリでは八以降で使えます。

13
00:01:12.404 --> 00:01:16.486
ノード・ジェイエスではゼロ・十二・ゼロ以降で対応しています。

14
00:01:16.486 --> 00:01:20.433
記事の互換性情報はエムディーエヌのデータに基づく目安です。

15
00:01:20.433 --> 00:01:25.876
前回学んだエニーと比べると対応範囲がとても広く、古い環境でも使えるのが特徴です。

16
00:01:25.876 --> 00:01:31.592
スライドの通り、プロミス・レースは関数として備わっていることを実機でも確認済みです。

17
00:01:31.592 --> 00:01:37.308
追加のパッケージは不要で、ブラウザーのコンソールでもノードでも同じコードで試せます。

18
00:01:37.308 --> 00:01:43.568
現在の主要ブラウザーとノードであれば、ほとんどの環境でそのまま動作すると考えてよいでしょう。

19
00:01:43.568 --> 00:01:44.943
書き方を確認します。

20
00:01:44.943 --> 00:01:48.793
プロミスのあとにドットを書き、レースとカッコを続けます。

21
00:01:48.793 --> 00:01:54.706
引数は一つだけで、プロミスや通常の値を含む、反復可能なオブジェクト、代表例は配列です。

22
00:01:54.706 --> 00:02:00.893
戻り値は新しいプロミスで、渡した中の一つが最初に決着すると、その結果にそのまま追従します。

23
00:02:00.893 --> 00:02:06.256
最初に成功すれば成功した値で履行され、最初に失敗すればその理由で拒否されます。

24
00:02:06.256 --> 00:02:12.306
スライドの例では、成功した値であるオーケーがそのまま取り出せることを実機で確認しました。

25
00:02:12.306 --> 00:02:16.981
引数を一つずつ並べるのではなく、配列にまとめて渡す点がポイントです。

26
00:02:16.981 --> 00:02:20.556
履行や拒否という言葉はプロミスの状態を表す用語です。

27
00:02:20.556 --> 00:02:23.118
前回のエニーとの違いを整理します。

28
00:02:23.118 --> 00:02:27.942
エニーは失敗したものを読み飛ばして、最初の成功だけを採用します。

29
00:02:27.942 --> 00:02:33.368
一方レースは、成功でも失敗でも、最初に決着した一件をそのまま採用します。

30
00:02:33.368 --> 00:02:41.357
スライドの通り、失敗と成功を並べた場合、レースでは失敗の理由であるエヌジーが返ることを実機で確認しました。

31
00:02:41.357 --> 00:02:48.442
選び方の目安は、一つでも成功が欲しいならエニー、失敗も含めて最初の結果が欲しいならレースです。

32
00:02:48.442 --> 00:02:53.114
名前と動きが似ているため、この一点に注目して区別してください。

33
00:02:53.114 --> 00:02:57.184
この違いが、記事でも最初に強調されているポイントです。

34
00:02:57.184 --> 00:02:58.869
記事の基本例を見ます。

35
00:02:58.869 --> 00:03:04.688
非同期関数の中で、すぐに成功する、先という文字列と、十ミリ秒ほどかかってから後という文字列で成功するプロミスを配列に並べ、

36
00:03:04.688 --> 00:03:10.507
レースに渡して結果を待ちます。

37
00:03:10.507 --> 00:03:14.489
実行結果は先で、ノードの実機結果とも一致しています。

38
00:03:14.489 --> 00:03:20.002
配列の並び順ではなく、決着した時刻の早さで結果が決まることが分かります。

39
00:03:20.002 --> 00:03:26.740
複数のサーバーへ同時に問い合わせて一番速い応答を使う、といった処理の土台になる動きです。

40
00:03:26.740 --> 00:03:33.785
まずはこの例をコンソールで実行し、待ち時間を変えたら結果がどう変わるか予測してみてください。

41
00:03:33.785 --> 00:03:37.766
時間差を逆にすると後が勝つことも確かめてみましょう。

42
00:03:37.766 --> 00:03:43.892
並び順が先だから有利、というわけではない点が、通常の配列処理との大きな違いです。

43
00:03:43.892 --> 00:03:45.867
記事の境界条件の例を見ます。

44
00:03:45.867 --> 00:03:49.888
先に失敗するプロミスと、成功するプロミスを並べると、レースは最初の失敗を採用するため、

45
00:03:49.888 --> 00:03:53.909
全体が失敗として扱われます。

46
00:03:53.909 --> 00:03:59.271
捕捉したエラーのメッセージは先に失敗で、ノードの実機結果とも一致しています。

47
00:03:59.271 --> 00:04:03.362
後から成功が届いても、すでに決まった結果は取り消せません。

48
00:04:03.362 --> 00:04:07.454
成功だけを待つ関数だと誤解すると、この動きでつまずきます。

49
00:04:07.454 --> 00:04:13.803
失敗を早く知りたい処理では便利な一方で、失敗を許容したい処理ではエニーの方が向いています。

50
00:04:13.803 --> 00:04:18.600
成功例だけでなく、こうした失敗の例も実行して確かめることが大切です。

51
00:04:18.600 --> 00:04:23.853
もう一つの境界条件として、空の配列を渡した場合を見ます。

52
00:04:23.853 --> 00:04:30.043
空の配列をレースに渡しても、その場でエラーにはならず、成功も失敗も決して届かないため、

53
00:04:30.043 --> 00:04:36.233
結果のプロミスは永久に待機中のままになります。

54
00:04:36.233 --> 00:04:41.486
実機でも、一定時間待っても決着しないことを確認しました。

55
00:04:41.486 --> 00:04:47.301
前回のエニーでは空入力がすぐにエラーになったのとは対照的です。

56
00:04:47.301 --> 00:04:53.586
そのため、候補の配列が空になる可能性のあるコードでは、呼び出す前に件数をチェックしないと、

57
00:04:53.586 --> 00:04:59.870
処理が止まったまま気付けない危険があります。

58
00:04:59.870 --> 00:05:04.372
境界条件は記事でも注意点として挙げられています。

59
00:05:04.372 --> 00:05:08.217
レースの代表的な応用が、タイムアウト競争です。

60
00:05:08.217 --> 00:05:14.571
本命の処理と、制限時間を表すタイマーを並べてレースに渡すと、処理が制限時間内に終わればその結果が採用され、

61
00:05:14.571 --> 00:05:20.924
タイマーが先に終われば時間切れとして扱えます。

62
00:05:20.924 --> 00:05:25.772
スライドの例では、十ミリ秒で終わるデータ取得と、三十ミリ秒のタイマーを競わせ、

63
00:05:25.772 --> 00:05:30.621
データが勝つことを実機で確認しました。

64
00:05:30.621 --> 00:05:33.964
待ち時間を逆にすればタイマーが勝ちます。

65
00:05:33.964 --> 00:05:40.485
通信がいつまでも返らない事態に備える仕組みとして、多くの現場で使われる形です。

66
00:05:40.485 --> 00:05:44.999
記事でもタイムアウト競争が用途として紹介されています。

67
00:05:44.999 --> 00:05:53.024
制限時間は用途に合わせて調整し、時間切れのときに利用者へどう伝えるかも合わせて設計してください。

68
00:05:53.024 --> 00:05:55.840
注意点の一つ目は、キャンセルの扱いです。

69
00:05:55.840 --> 00:06:02.317
レースで勝者が決まっても、負けた処理は自動ではキャンセルされず、裏側で最後まで動き続けます。

70
00:06:02.317 --> 00:06:10.343
スライドの例でも、速い成功が表示されたあとに、遅い処理の完了メッセージが続いて表示されることを実機で確認しました。

71
00:06:10.343 --> 00:06:14.285
タイムアウト競争でも、負けた通信そのものは止まりません。

72
00:06:14.285 --> 00:06:18.157
不要になった通信を止めたい場合は、アボートコントローラーなどを併用する必要がある、

73
00:06:18.157 --> 00:06:22.029
と記事でも案内されています。

74
00:06:22.029 --> 00:06:26.676
結果が決まった時点で処理がすべて終わった、とは考えないでください。

75
00:06:26.676 --> 00:06:29.459
注意点の二つ目は、引数の渡し方です。

76
00:06:29.459 --> 00:06:33.635
配列の中にプロミスでない通常の値を混ぜると、その値は最初から成功したものとして扱われ、

77
00:06:33.635 --> 00:06:37.810
即座に勝者になります。

78
00:06:37.810 --> 00:06:46.006
スライドの通り、プレーンという文字列と成功を並べると、文字列がそのまま採用されることを実機で確認しました。

79
00:06:46.006 --> 00:06:52.501
また、配列のような反復可能なオブジェクトでない値を渡すと、タイプエラーが発生します。

80
00:06:52.501 --> 00:06:57.758
候補を用意する側で、値がプロミスなのか通常の値なのかを混同すると予想と違う結果になるため、

81
00:06:57.758 --> 00:07:03.016
渡す前に中身をそろえて確認する習慣が大切です。

82
00:07:03.016 --> 00:07:03.887
まとめです。

83
00:07:03.887 --> 00:07:12.019
プロミス・レースは、複数の候補の中から最初に決着した一件の結果を、成功でも失敗でもそのまま採用するメソッドです。

84
00:07:12.019 --> 00:07:13.761
導入時の判断は三つです。

85
00:07:13.761 --> 00:07:18.553
まず、失敗も含めて最も早い結果が欲しい処理かどうかを確認すること。

86
00:07:18.553 --> 00:07:23.781
次に、空の配列では決して決着しないため、候補の件数を事前に確認すること。

87
00:07:23.781 --> 00:07:28.573
そして、勝者が決まっても他の処理は止まらない点に注意することです。

88
00:07:28.573 --> 00:07:35.543
まずは記事の基本例をコンソールで実行し、待ち時間や失敗の有無を変えて結果を予測してみてください。

89
00:07:35.543 --> 00:07:42.368
エニーとレースの違いを説明できるようになると、プロミスの組み合わせで迷う場面がぐっと減ります。

90
00:07:42.368 --> 00:07:43.675
お疲れさまでした。

91
00:07:43.675 --> 00:07:46.724
次回はプロミス・オールセトルドを学びます。
