Home > JavaScript > 連続するページの JSONP を取得して最後に Callback 関数を呼ぶライブラリ

連続するページの JSONP を取得して最後に Callback 関数を呼ぶライブラリ

拙作のツール、「Twitter Stream Viewer」や「Twitter Follow Manager(作成中)」で、Twitter API から複数ページを取得するロジックがあるんですが、そのロジックがスマートではないのでライブラリを作ってみました。
使ってみたら結構便利だったので公開してみます。

jsonPageLoader

使い方はこんな感じです。

var loader = new jsonPageLoader({
  url     : 'http://twitter.com/statuses/friends.json',
  start   : 1,
  end     : function(result) { return result.length > 0; },
  onStart : function(page) { alert(page + 'ページ目の取得開始'); },
  onEnd   : function(result, page) { alert(page + 'ページ目の取得完了'); },
  callback: function(results, start, end) { alert('全ページの取得完了'); }
});

オブジェクトを new してあげて、引数にハッシュ形式でオプションを渡します。
url にはベースとなる URL を指定します。
start には開始するページ番号を指定します。省略すれば 1 ページ目からになります。
end には終了するページ番号または関数を指定します。必須。
5 と指定すれば 5 ページ目まで取得して処理が終了します。
関数を指定した場合、各ページの取得完了時に結果を引数としてこの関数が呼び出されます。false が返されるまでページ番号を 1 ずつ増やしながら処理が続行されます。上の例の場合、取得結果が 0 件になったところで処理が終了します。
onStart, onEnd は各ページの処理開始・終了時に呼び出される関数を指定します。省略可。
callback は全ページの取得完了時に呼び出される関数を指定します。引数の results はページ毎の結果を格納した配列です。ページ番号と添字が一致しています。

ライブラリのソースは以下で。

/*
 * jsonPageLoader
 *
 * version: 1.0
 * author: yusuke0927
 * url: http://www.sukechan.net/
 */

/* ---------------------------------- */

/* Parameter
 *
 * url            : 必須。
 * callbackString : callback パラメータ名を指定します。指定しなければ 'callback' になります。
 * pageString     : page パラメータ名を指定します。指定しなければ 'page' になります。
 * start          : 開始ページ数を指定します。指定しなければ 1 ページ目から取得します。
 * end            : 必須。終了ページ数、または処理を継続するかどうかの関数を指定します。
                    関数の場合、各ページ取得毎に実行され、false を返せば処理が終了します。引数は現在ページの取得結果です。
 * onStart        : 各ページの JSONP 取得開始時に呼び出される関数を指定します。引数はページ数です。
 * onEnd          : 各ページの JSONP 取得完了時に呼び出される関数を指定します。引数は当該ページの取得結果とページ数です。
 * callback       : 全ページの JSONP 取得完了時に呼び出される関数を指定します。引数はページ番号を添字とした配列と開始、終了ページ数です。
 */

/* ---------------------------------- */

function jsonPageLoader(option) {
  this.id = (new Date()).getTime();
  this.url = option.url;
  this.results = [];
  this.page = option.start || 1;
  this.pageString = option.page || 'page';
  this.end = option.end;
  this.onStart = option.onStart;
  this.onEnd = option.onEnd;
  this.callback = option.callback;
  this.callbackString = option.callbackString || 'callback';

  if((this.url) && ((typeof(this.end) == 'function') || (typeof(this.end) == 'number'))) {
    this.request(this.page);
  }
}

jsonPageLoader.prototype.request = function() {
  var self = this;
  var url = '';
  var callbackName = 'jsonPageLoader' + self.id + '_' + self.page;
  url = self._setQueryString(self.url, self.pageString, self.page);
  url = self._setQueryString(url, self.callbackString, callbackName);

  if(self.onStart) {
    self.onStart(self.page);
  }

  var s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = url;
  s.charset = 'UTF-8';
  document.getElementsByTagName('head')[0].appendChild(s);

  window[callbackName] = function(result) {
    if(self.onEnd) {
      self.onEnd(result, self.page);
    }
    self.results[self.page] = result;

    if((typeof(self.end) == 'function') && (self.end(result))) {
      self.page++;
      self.request();
    } else if((typeof(self.end) == 'number') && (self.page < self.end)) {
      self.page++;
      self.request();
    } else {
      self.callback(self.results, self.start, self.page);
    }

    window[callbackName] = undefined;
    try {
      delete window[callbackName];
    } catch(e) {
      document.getElementsByTagName('head')[0].removeChild(s);
    }
  }
}

jsonPageLoader.prototype._setQueryString = function(url, key, value) {
  var qs = this._parseQueryString(url);
  if(qs) {
    qs[key] = value;
    var idx = url.indexOf('?');
    if(idx > -1) {
      url = url.substring(0, idx);
    }
    return this._createQueryString(url, qs);
  }
}

jsonPageLoader.prototype._parseQueryString = function(url) {
  if((typeof(url) != 'string') || (url.length == 0)) return null;
  var qs = new Array();
  var idx = url.indexOf('?');
  if(idx > -1) {
    var arr = url.substr(idx + 1).split('&');
    for(var i in arr) {
      var x = arr[i].split('=');
      qs[x[0]] = x[1];
    }
  }
  return qs;
}

jsonPageLoader.prototype._createQueryString = function(url, arr) {
  var qs = '';
  if(arr) {
    for(var i in arr) {
      qs += ((qs.length == 0) ? '?' : '&') + i + '=' + arr[i];
    }
  }
  return url + qs;
}

参考リンク

関連する記事

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.sukechan.net/archives/179/trackback/
Listed below are links to weblogs that reference
連続するページの JSONP を取得して最後に Callback 関数を呼ぶライブラリ from sukechan.net

Home > JavaScript > 連続するページの JSONP を取得して最後に Callback 関数を呼ぶライブラリ

Search
Feeds
Meta
あわせて読みたい
あわせて読みたいブログパーツ
Others...
フィードメーター - sukechan.net
track feed

Return to page top