Scalaはじめました

posted by cheesepie on 2009.08.28, under scala
28th

最初は関数型絶対肌に合わんと思ってたけど、触ってみると
以外といけそうな気がしてきたので、Scalaの勉強始めます。

いや、言語としては相当いい感じですよね。
Javaの静的なところとRubyのキレイに書けるところを上手く
合わせたみたいな。

ということで、事始めに文法注意書きメモ。

valとvar
再代入できる変数はvar、再代入できないのがval
関数型指向でいくなら、varを使わないような記述を心がける
staticな関数作りたい時
クラスは静的メンバを持てないので、代わりにobjectを使って実装する
リストとタプル
共にイミュータブルだけど、違う型の値を持てるのがタプル。
リストに「::」で値を追加する際、最後にNilを追加するのが何か慣れない

しばらくは言語自体の勉強して、それから何かアプリを作っていこう。GAEでも動くみたいですし。

FirefoxでAjax中にF5押したとき

posted by cheesepie on 2009.08.07, under javascript
07th

Ajaxでのコンテンツ取得に時間がかかっている時に、画面をreloadすると、Firefoxだけreload後にエラー処理が実行された。

例えば、ブラウザ側では

$.ajax( {
  type: "get",
  url: "test.php",
  data: queryString,
  success: function(msg){
    alert( "Success! " + msg );
  },
  error: function( msg ) {
    alert( "Error! " + msg );
  }
} );

で、サーバ側では時間がかかるようにsleep(10)とかしといて、待ってる間にブラウザをreloadしてみます。
すると、XHRがabortされずにエラーハンドラが実行されちゃう。

エラーハンドラが実行されてしまうのは、リロードされるタイミングでreadyStateは4なのに、statusが0(ってか空っぽ)が返ってきて、エラー処理まで到達してしまうからなんだけど、XHRってreload関係なく引き継がれるのか。。。
IEとSafariはよしなにabortしてくれてるみたい。

Firefoxで”readyState”が4なのに”status”が0ってのは仕様らしくて、その場合”responseText”があるかどうかでabortするか判定できる。
ちなみにjQueryの$.ajax関数は対応してないorz
そもそも、まだレスポンスが返ってきていないので、readyStateは1を返すべきですが。

でもreloadのケースの場合、reloadされるタイミングでabortしないといけないので、上の対応をしてもどうしようもない。

ということで、MDCを見たら”onBeforeUnload”というドンピシャなイベントを発見。

$( document ).bind( 'beforeUnload', function() {
  xhr.abort();
} );

これでエラーが出なくなりましたー。ヒャッハー!
勉強になりました。

HTML5を勉強していく

posted by cheesepie on 2009.08.05, under html5, javascript
05th

ちょっと早く帰れた日は、HTML5を勉強していくよ!

で、早速Web Workersを触ってみました。

バックグラウンドで処理を実行してくれる上に、マルチスレッドで動いてくれるらしい。しかもマルチコアCPU対応とのこと・・!
これまでのJavaScriptはシングルスレッドなので、setTimeout()使って無理くり並列で処理させていたのが、これでだいぶスッキリできる、、のか?

チュートリアルを参考に、フィボナッチ数列の計算をバックグラウンドで実行してみました。

sample.html内

// workers
var start1 = new Date();
var worker1 = new Worker('job1.js');
worker1.onmessage = function (event) {
  document.getElementById('result1').textContent = (new Date() - start1) + "ms, " + event.data;
};

job1.js

function fib( num ) {
  var list = {};
  var _fib = function( n ) {
    if( list[n] ) return list[n];
    if( n <= 2 ) return 1;
    return list[n] = _fib(n-1) + _fib(n-2);
  }
  for( var i = 1; i <= num; i++ ) {
    postMessage( _fib( i ) );
  }
  return list;
};
fib( 1000 );

おー何か楽しい。

HTMLとWorkerのやりとりはシンプルで、
Workerから postMessageで HTMLに通知を送り、
HTML側ではWorkerインスタンスの onmessage イベントで通知を受け取れます。
逆にHTMLからWorkerに通知を送ることはできないみたい。
(ストップとかできないのかな?調べよう)
また、HTML側で定義した関数や変数はWorker内で利用できないので、Worker内に全て記述する必要があります。

HTMLとWorkerで相互にデータをやりとりする場合は、
HTML側で
・workerをインスタンス化
・何かトリガーになる関数で、worker.postMessage( value )
・workerからの結果受け取りのためのworker.onmessage( event )
Worker側で
・onmessage( event ) 内で、postMessage( result )

みたいにやれば、相互にやりとりが可能です。
実際に使う場合は、ラッパを作ってしっかり汎用化しないとカオスな感じになりそうですが。。。

ちなみに、WebSocketはまだSafari4でもFF3.5でも未実装みたい。

次はShared Workerを見ていくお。

pagetop