VIDEO LESSON

JavaScriptのPromise.race()の使い方:引数・戻り値・実例と注意点の解説動画

再生時間 7:47動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:01今回はジャバスクリプトのプロミス・レースを紹介します。
  3. 0:06これは、複数の非同期処理を同時に走らせて、その中で最初に決着した一件の結果をそのまま採用するための仕組みです。
  4. 0:16決着というのは、成功して終わることと、失敗して終わることの両方を含みます。
  5. 0:23つまりレースでは、最初に終わったのが失敗なら、全体も失敗になります。
  6. 0:29この動画では、書き方と引数、エニーとの違い、記事の基本例と、最初の失敗や空入力といった境界条件、
  7. 0:38タイムアウトへの応用、そして負けた処理が止まらない注意点まで、実行結果と一緒に学びます。
  8. 0:46名前の通り競争させる発想が中心になるメソッドです。
  9. 0:51複数の候補を順番に待つのではなく、同時に走らせて一番乗りを採用する、という発想をまず押さえてください。
  10. 1:00まず動作環境を確認します。
  11. 1:02プロミス・レースは昔からある機能で、クロームでは三十二以降、エッジでは十二以降、
  12. 1:07ファイアーフォックスでは二十九以降、サファリでは八以降で使えます。
  13. 1:12ノード・ジェイエスではゼロ・十二・ゼロ以降で対応しています。
  14. 1:16記事の互換性情報はエムディーエヌのデータに基づく目安です。
  15. 1:20前回学んだエニーと比べると対応範囲がとても広く、古い環境でも使えるのが特徴です。
  16. 1:25スライドの通り、プロミス・レースは関数として備わっていることを実機でも確認済みです。
  17. 1:31追加のパッケージは不要で、ブラウザーのコンソールでもノードでも同じコードで試せます。
  18. 1:37現在の主要ブラウザーとノードであれば、ほとんどの環境でそのまま動作すると考えてよいでしょう。
  19. 1:43書き方を確認します。
  20. 1:44プロミスのあとにドットを書き、レースとカッコを続けます。
  21. 1:48引数は一つだけで、プロミスや通常の値を含む、反復可能なオブジェクト、代表例は配列です。
  22. 1:54戻り値は新しいプロミスで、渡した中の一つが最初に決着すると、その結果にそのまま追従します。
  23. 2:00最初に成功すれば成功した値で履行され、最初に失敗すればその理由で拒否されます。
  24. 2:06スライドの例では、成功した値であるオーケーがそのまま取り出せることを実機で確認しました。
  25. 2:12引数を一つずつ並べるのではなく、配列にまとめて渡す点がポイントです。
  26. 2:16履行や拒否という言葉はプロミスの状態を表す用語です。
  27. 2:20前回のエニーとの違いを整理します。
  28. 2:23エニーは失敗したものを読み飛ばして、最初の成功だけを採用します。
  29. 2:27一方レースは、成功でも失敗でも、最初に決着した一件をそのまま採用します。
  30. 2:33スライドの通り、失敗と成功を並べた場合、レースでは失敗の理由であるエヌジーが返ることを実機で確認しました。
  31. 2:41選び方の目安は、一つでも成功が欲しいならエニー、失敗も含めて最初の結果が欲しいならレースです。
  32. 2:48名前と動きが似ているため、この一点に注目して区別してください。
  33. 2:53この違いが、記事でも最初に強調されているポイントです。
  34. 2:57記事の基本例を見ます。
  35. 2:58非同期関数の中で、すぐに成功する、先という文字列と、十ミリ秒ほどかかってから後という文字列で成功するプロミスを配列に並べ、
  36. 3:04レースに渡して結果を待ちます。
  37. 3:10実行結果は先で、ノードの実機結果とも一致しています。
  38. 3:14配列の並び順ではなく、決着した時刻の早さで結果が決まることが分かります。
  39. 3:20複数のサーバーへ同時に問い合わせて一番速い応答を使う、といった処理の土台になる動きです。
  40. 3:26まずはこの例をコンソールで実行し、待ち時間を変えたら結果がどう変わるか予測してみてください。
  41. 3:33時間差を逆にすると後が勝つことも確かめてみましょう。
  42. 3:37並び順が先だから有利、というわけではない点が、通常の配列処理との大きな違いです。
  43. 3:43記事の境界条件の例を見ます。
  44. 3:45先に失敗するプロミスと、成功するプロミスを並べると、レースは最初の失敗を採用するため、
  45. 3:49全体が失敗として扱われます。
  46. 3:53捕捉したエラーのメッセージは先に失敗で、ノードの実機結果とも一致しています。
  47. 3:59後から成功が届いても、すでに決まった結果は取り消せません。
  48. 4:03成功だけを待つ関数だと誤解すると、この動きでつまずきます。
  49. 4:07失敗を早く知りたい処理では便利な一方で、失敗を許容したい処理ではエニーの方が向いています。
  50. 4:13成功例だけでなく、こうした失敗の例も実行して確かめることが大切です。
  51. 4:18もう一つの境界条件として、空の配列を渡した場合を見ます。
  52. 4:23空の配列をレースに渡しても、その場でエラーにはならず、成功も失敗も決して届かないため、
  53. 4:30結果のプロミスは永久に待機中のままになります。
  54. 4:36実機でも、一定時間待っても決着しないことを確認しました。
  55. 4:41前回のエニーでは空入力がすぐにエラーになったのとは対照的です。
  56. 4:47そのため、候補の配列が空になる可能性のあるコードでは、呼び出す前に件数をチェックしないと、
  57. 4:53処理が止まったまま気付けない危険があります。
  58. 4:59境界条件は記事でも注意点として挙げられています。
  59. 5:04レースの代表的な応用が、タイムアウト競争です。
  60. 5:08本命の処理と、制限時間を表すタイマーを並べてレースに渡すと、処理が制限時間内に終わればその結果が採用され、
  61. 5:14タイマーが先に終われば時間切れとして扱えます。
  62. 5:20スライドの例では、十ミリ秒で終わるデータ取得と、三十ミリ秒のタイマーを競わせ、
  63. 5:25データが勝つことを実機で確認しました。
  64. 5:30待ち時間を逆にすればタイマーが勝ちます。
  65. 5:33通信がいつまでも返らない事態に備える仕組みとして、多くの現場で使われる形です。
  66. 5:40記事でもタイムアウト競争が用途として紹介されています。
  67. 5:44制限時間は用途に合わせて調整し、時間切れのときに利用者へどう伝えるかも合わせて設計してください。
  68. 5:53注意点の一つ目は、キャンセルの扱いです。
  69. 5:55レースで勝者が決まっても、負けた処理は自動ではキャンセルされず、裏側で最後まで動き続けます。
  70. 6:02スライドの例でも、速い成功が表示されたあとに、遅い処理の完了メッセージが続いて表示されることを実機で確認しました。
  71. 6:10タイムアウト競争でも、負けた通信そのものは止まりません。
  72. 6:14不要になった通信を止めたい場合は、アボートコントローラーなどを併用する必要がある、
  73. 6:18と記事でも案内されています。
  74. 6:22結果が決まった時点で処理がすべて終わった、とは考えないでください。
  75. 6:26注意点の二つ目は、引数の渡し方です。
  76. 6:29配列の中にプロミスでない通常の値を混ぜると、その値は最初から成功したものとして扱われ、
  77. 6:33即座に勝者になります。
  78. 6:37スライドの通り、プレーンという文字列と成功を並べると、文字列がそのまま採用されることを実機で確認しました。
  79. 6:46また、配列のような反復可能なオブジェクトでない値を渡すと、タイプエラーが発生します。
  80. 6:52候補を用意する側で、値がプロミスなのか通常の値なのかを混同すると予想と違う結果になるため、
  81. 6:57渡す前に中身をそろえて確認する習慣が大切です。
  82. 7:03まとめです。
  83. 7:03プロミス・レースは、複数の候補の中から最初に決着した一件の結果を、成功でも失敗でもそのまま採用するメソッドです。
  84. 7:12導入時の判断は三つです。
  85. 7:13まず、失敗も含めて最も早い結果が欲しい処理かどうかを確認すること。
  86. 7:18次に、空の配列では決して決着しないため、候補の件数を事前に確認すること。
  87. 7:23そして、勝者が決まっても他の処理は止まらない点に注意することです。
  88. 7:28まずは記事の基本例をコンソールで実行し、待ち時間や失敗の有無を変えて結果を予測してみてください。
  89. 7:35エニーとレースの違いを説明できるようになると、プロミスの組み合わせで迷う場面がぐっと減ります。
  90. 7:42お疲れさまでした。
  91. 7:43次回はプロミス・オールセトルドを学びます。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Promise.race()で最初に決着した非同期処理の結果を採用する方法を解説。引数と戻り値、実行結果付きのコード、間違えやすい点、ブラウザー・Node.js対応を確認できます。

解説記事・サンプルコードを読む:JavaScriptのPromise.race()の使い方:引数・戻り値・実例と注意点 →