getURL()の挙動を調べる(その1)
とある事情で受け取ったflaファイルに、次のようなactionscriptが記述されていました。
getURL('javascript:doSomething()'); getURL('./somewhere.html');
これをパブリッシュすると、2つ目のgetURL()の呼び出しだけが実行されるのが確認できます。
どうして、そのような挙動になるのか動作検証をしながら原因を究明していこうと思います。
そもそもgetURL()ってどういう関数なのか?
まずはFlash CS3 ドキュメンテーションの説明を見てみましょう。
特定の URL からウィンドウにドキュメントをロードしたり、定義済みの URL に存在する別のアプリケーションに変数を渡したりします。
つまりこの関数を使うと、Flashが読込まれたwindowに別なURLのhtmlを読込むことなどができます。また、"javascript:"疑似プロトコルを指定するとswfがロードされたhtml内のjavascript関数を呼び出すことが出来ます。
疑問その1:getURL()は非同期呼び出しか?
getURL()の仕様がわかったところで、そもそもgetURL()は、非同期呼び出しなのか?という根本的な疑問から確認していきたいと思います。最初のコードでgetURL()が呼び出された順番通りに実行されていないことからgetURL()の呼び出しは非同期呼び出しである可能性が高いですが、念のため動作確認を行います。
確認方法
FlashからgetURL()を使って、処理時間のかかるjavascriptの関数を呼び出します。その直後にactionscriptの関数を記述し、その挙動を調べます。
もしjavascriptの処理が終了後にactionscriptの関数が呼び出された場合はgetURL()の呼び出しは同期呼び出しだと言えます。逆に、javascriptの処理が完了する前にactionscriptが呼び出された場合は、getURL()はjavascriptの処理を待たないで返ってきているので非同期呼び出しだと言えます。
この確認のために次のようなjavascriptとactionscriptを書いてみました。
javascriptは次の通りです。func1()は、引数で渡された整数のフィボナッチ数を計算してalertで表示します。
function fib(n) { if ( n < =2 ) return 1; return fib(n - 1) + fib(n - 2); } function func1(num) { var ret = fib(num); alert('func1: fib(' + num + ')=' + ret); }
これに対して、Flash側は次のようなものを作りました。
ステージ上に、求めるフィボナッチ数を入力するテキストフィールドと「フィボナッチ数を計算する」ボタン、メッセージを表示するテキストフィールド、メッセージのクリアボタンの4つを配置します。
以下は、「フィボナッチ数を計算する」ボタンが押されときのイベントハンドラです。
on(release) { var num:Number = parseInt(fibnum.text); if ( num > 0 ) { getURL('javascript:func1(' + num + ')'); msg.text = "after func1()"; } }
まず、テキストフィールドに入力された値をNumberに変換し0より大きければgetURL()を呼び出します。getURL()の引数にはさきほど変換した値を引数としたfunc1()を呼び出すためのURLを指定します。
また、getURL()の呼び出し直後にメッセージをテキストフィールドに書き込んでいます。
動作結果
実際にここから動作を確認することができます。(※注意 35とか大きい数字を入力するとブラウザが固まる場合があるので自己責任で御願いします)
テキストボックスに適当な数値(私の環境では25〜30くらいが丁度でした)を入力して、何度か入力してみるとFlash側のメッセージ表示が先に行われ、その後、javascriptのalertが表示されることが確認できます。つまり、getURL()の呼び出し後すぐに次のスクリプトの処理に移っておりgetURL()の呼び出しは非同期呼び出しだということがわかります。
結論
getURL()は非同期呼び出しで間違いないようです。しかし、最初のコードの挙動を説明するにはまだ検証が足りません。今後、何回かにわけてこの問題を調べて行こうと思います。
ダウンロード
ソースファイル一式は、こちらからダウンロードできます。
補足
FireFoxで動作を確認した場合は、alertが先に表示される時があるようです。ただ、Flash側が先に呼び出されることもあることからgetURL()の呼び出しが非同期呼び出しであることは間違いありません。しかし、getURL()を呼び出した後の実行順序が何故ブラウザによって異なるのかは今のところ原因不明です。
参考URL
- Flash CS3 ドキュメンテーション getURL()のヘルプです
- 404 Blog Not Found フィボナッチ数列を求めるきちんとしたアルゴリズムが紹介されています