5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

条件を満たすまで $.ajax を繰り返し続けるサンプル

Last updated at Posted at 2018-11-14

あらすじ

Qiitaのリニューアル前に記事ページの右カラムに表示されていた 人気の投稿 をローカル環境で復活させようと思い、APIにリクエストをして投稿データを取得し、いいねの多い上位5件のタイトルとURLを取り出して、右カラムにHTMLで追加する、という処理を UserScript で書いたのですが、APIのリクエスト回数制限に引っかかって 泣く泣くお蔵入りしました。(実装する前に気づけよ)

* 本当はこんなの作ろうとしてました

貼り付けた画像_2018_11_13_17_31_3.png

リニューアル以前の Qiita でこんなのあったかとおもいます。一応期待どおり動きはしたんですが、リクエスト回数がすぐ上限に達してしまうので使い物にならないのが現状です。悔しい。

じゃあ今日は何の話か

前項に書いた 全件取得するまで $.ajax を呼び続ける というパターンはわりと今後も出番ありそうかとおもいましたため、今日は作ったコードをサンプルとして公開してみたいと思います。

検証ブラウザ

  • Google Chrome(70.0.3538.77)

IEだとたぶん動かないです。

サンプルコード

というわけでこれが全件取得するまで $.ajax を呼び続けるコード例です。(jQuery は事前に読み込まれているものとします。)
私の場合は Qiita の API の仕様が最大でも100件づつしか取得できない というものであったため、記事が100件以上あるユーザーの場合は何度も $.ajax を呼ぶ必要があったことからこのようなコードが必要になりました。

※更新:わかりやすくするため処理の骨子を残して余計なものはごっそりカットしました。当初作ったコードを見てみたい方はお手数ですがこの記事の編集履歴から過去のコードをご覧ください。

(function($){
  //1回のAPIリクエストで取得する件数
  const perPage = 100;

  //fetchPosts が実行されるたびここに記事が貯まります
  let posts = [];

  //APIからデータを取得します
  const fetchPosts = (userId, page) => {
    return $.ajax({
      type: "get",
      url: "//example.com/path/to/api",
      data: {
        user_id: userId
        page: page,
        per_page: perPage
      }
    }).then(items => {
      //取得結果を貯める
      posts = posts.concat(items);

      //次ページがありそうなときは再帰呼び出し
      if(items.length == perPage) {
        fetchPosts(userId, page++);
      }

      return posts;
    });
  };

  //Main
  $(function(){
    const page = 1;

    //fetchPosts は Promise を返すので then で続けて処理が書けます
    fetchPosts(userId, page).then((posts) => {

      //APIで取得したデータを使っていろいろやる

    });
  });
})(jQuery);

この処理の要点

下記の部分です。再帰呼び出し をすることでわりとあっさり実現できました。また、この if 文の条件で繰り返し処理の継続如何をコントロールできます。fetchPosts は Promise ごと返して、ソートなどの後処理は大元の呼び出し側に任せています。

if(items.length == perPage) {
  fetchPosts(userId, page++);
}

感想

当初、while文内で $.ajax するようなコードを書いてうんうん唸っていたのはいい思ひ出(遠い目
ちなみにこの人気の投稿欄復活は諦めていないので、何か別の作戦を考えてまたリベンジしたいと思います。

※2018/11/21追記
リベンジしてみました。
[Qiita]なつかしの "人気の投稿" 欄を UserScript で復活させる(β版) - Qiita

参考

5
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?