コンテンツ一覧を表示するページなど、表示するアイテムの件数が多い場合は、サーバへの問い合わせを毎回せずキャッシュを使う場面がよくあります。 加えて、ユーザおすすめのコンテンツを最上部に表示したり、既読のコンテンツを隠したり、端末の向きに合わせて表示方法を変えたりと、取得したデータをクライアント側で加工したい場面なんかもあったりします(もちろん全部サーバ側でやることも可能です)。

そんなことをスマートにこなせるPromise.race()の使い方をメモしますよ😌💡

実装する仕様

ユーザが選択したカテゴリーのコンテンツを取得して表示するとします。サーバから取得したコンテンツリストの中にユーザのお気に入りのタグのものがあれば「お気に入りフラグ」を立てます(サーバ取得時のみ行う)。表示するときは、localStorageにキャッシュされた既読コンテンツと照らし合わせて、既読のものは表示しないようにします。

処理の流れはこんな感じ。

  1. データが既にキャッシュされていたらそこから取得する
  2. キャッシュがなければサーバから取得する
  3. とってきたものを加工する
     →サーバから取得した場合はお気に入りチェック&既読チェック
     →キャッシュから取得した場合は既読チェックのみ
  4. サーバから取得した場合はキャッシュする
  5. 後続処理をできるようにPromiseをreturnする

実装のポイント

出てきましたね、Promise.race()👆
こいつは、Iteratableの引数をとって、それらを並行処理し最も早く結果が返ったものを採用します。この例だと_getFromCache_getFromServerの2つのPromiseのうち、先にresolveまたはrejectを返したものが採用されるというわけです😉

_getFromCache_getFromServerの(A)〜(D)に実装していきます。

(A) キャッシュからコンテンツリストを取得する処理
(B) 既読のもを表示しないようにする処理
(C) サーバからコンテンツリストを取得する処理
(D) お気に入りフラグ付けと既読のものを表示しないようにする処理

おわりに

こういうのは実践で使ってみないと覚えないし、良さも悪さも実感できないもんですね。何だかんだ初めて使ったメソッドだったので備忘録も兼ねて、でした。