GreaseMonkeyのGM_xmlhttpRequestで同期通信(モドキ)
キーボードが打ちたいので文章作成。
2007/06/05現在、GM_xmlhttpRequestが同期通信できません。(多分)
なので、繰り返しGM_xmlhttpRequestを行う時に、こんなことをやると・・・・
// 関数foo を通信の1単位 var foo = function(){ GM_xmlhttpRequest({ method: "GET", url: "http://ドコカ", header: { "User-Agent": "gmonkeyagent", }, onload: function(r){ alert(ReqCount); } }); } // foo後、+1される変数 var ReqCount = 0; // 関数foo を5回使ってみる。 for(var i=0; i<5; i++){ foo(); ReqCount += 1; }
なんて書くと・・・・
接続先にもよるが大抵の場合「5」と表示されたアラート画面が五回出てくるだけになる。
原因は・・・
非同期通信だから、通信をはじめても処理は待ってくれない。
故に五回の通信が完了するころには、5回ループが終わってる状態なんですね。
解決方法としては二つ考えた。
** 解決方法その1 ** GM_xmlhttpRequestを使わない。
ネガティブな解決方法。自分はやったこと無い。
もともとブラウザが持ってるjavascriptの通信関数を使う。
GMスクリプトの対象となっているサイトがprototype.js等を読み込んでるんだったら、unsafeWindowを使って頑張ればできる。(はず)
参考:http://d.hatena.ne.jp/daftbeats/20070519/1179570856
というか、GMでprototype.jsのオブジェクトAjax.requestのインスタンス生成がうまくできないのですよ。
** 解決方法その2 ** GM_xmlhttpRequestを再帰
うん。GM_xmlhttpRequestの変数onloadの中でGM_xmlhttpRequestを使うんですよ。
上のコードを書き換えると、
// 関数foo を通信の1単位 // 引数nは繰り返しの回数。 var foo = function(n){ if(n==0){ return 0; } GM_xmlhttpRequest({ method: "GET", url: "http://ドコカ", header: { "User-Agent": "gmonkeyagent", }, onload: function(r){ alert(ReqCount); ReqCount += 1; foo(n-1); // 最後に「引数を-1した自分自身」を呼び出す。 } }); } // foo後、+1される変数 var ReqCount = 0; // 関数foo を5回使ってみる。 foo(5);
こう。
** 解決方法その2 ** の問題点
- みづらい。
通信の一単位とは言えない状態になってます。
以上です。
他にいい方法無いかなぁ。