プロが教える店舗&オフィスのセキュリティ対策術

テキスト・ファイルを読み込みについての解説で、

基本的な流れは,
1. LoadVarsクラスのインスタンスを生成
2. 読み込んだあとの処理を作成(onLoadイベントハンドラの設定)
3. 読み込み

- スクリプト -
var textReaderLV:LoadVars = new LoadVars();
textReaderLV.onLoad = function() {
trace("「hoge」の値は," + textReaderLV.hoge);
};
textReaderLV.load("data.txt");

という説明が書かれているのですが、2と3が逆のような気がしてしまうのですが、3番目に読み込みとなっている事には何か意味があるのでしょうか?
一応、2と3を入れ替えてプレビューしたところ特に問題なかったのですが、上記は学習のためにシンプルに書かれたスクリプトなので、もしかしたら本来的な意味合いで、3番目に読み込みが来る事に何か意味があるのかな??と思い質問させていただきました。

LoadVarsによるテキストファイルの読み込みをするとき、上記のような流れで読み込み後の処理を先に実行し、後から読み込みとするのはなぜなのでしょうか?
ご教授やアドバイスなどいただけたらと思います。
よろしくお願いします。

A 回答 (4件)

#1,2 です。


申し訳ありませんが,同じ事を別の角度から何度も説明しているため,この回答はくどく,長くなってしましました。
あらかじめご了承下さい。


> すべてコードは上から順に処理が進み、
> その処理が終わると次の行へ進むという理解なのですが、
> どうもここの辺りで私の勘違いがあるようなのですが、

そこには勘違いはないと思います。
基本的に上から順に処理が進みます。
だからこそ,
LoadVars.onLoad = function() { } の定義は,実際の読み込みが行われる前に定義しておかなければならないのです。
先に定義しておかなければ,実行ができません。


~~~ ~~~ ~~~ ~~~ ~~~ ~~~

なんとなくですが,
「関数の定義」と「関数の実行」を同じもの(同時に起こるもの)として考えていらっしゃるのではないかと思います。
「関数の定義」は「関数の定義」であって,実行命令が下らないと実行はされません。

LoadVars.onLoad = function() {○○}; は「関数の定義」です。
「ロード処理完了時には○○という動作をする」という定義をしているだけで,
LoadVars.load(); のロード処理が実行されない限り何にもしないのです。

仮に,普通通り,

 LoadVarsインスタンスの作成
 LoadVars.onLoad = function() {○○};
 外部テキストのロード

という順にスクリプトを書いたとします。
これがどう実行されるかを「超スローモーション」で書くと次のようになります。

 LoadVarsインスタンスが作成される
   ↓
 LoadVars.onLoad が定義される
   ↓
 外部テキストのロードが開始される
   ↓
 外部テキストのロードが完了する
   ↓とれと同時に
 定義しておいた LoadVars.onLoad が実行される


次に,質問者様の書かれていらっしゃるように,

 LoadVarsインスタンスの作成
 外部テキストのロード
 LoadVars.onLoad = function() {○○};

という順にスクリプトを書いたとします。
これがどう実行されるかを超スローモーションで書くと次のようになります。

 LoadVarsインスタンスが作成される
   ↓
 外部テキストのロードが開始される
   ↓
 LoadVars.onLoad が定義される
   ↓
 外部テキストのロードが完了する
   ↓とれと同時に
 定義しておいた LoadVars.onLoad が実行される


ですから,
「LoadVars.onLoad の定義」 と 「外部テキストのロード」 のどちらを先に書いても,
結果は 「定義しておいた LoadVars.onLoad が実行される」 で同じになります。

しかし,見るからに実行の流れが変で,危ういとは思いませんか?
ロード開始 と ロード完了 の間に LoadVars.onLoad が定義される のです。
私はかなり危ういと思います。

「果たして犯人はそんな危ない橋を渡るだろうか?」
「私ならそんな危ない橋は渡らない。完全犯罪になりえない。」
と思います。
(あの,誰も犯人ではなくミステリーでもありません。一種のボケですので深く考えないでください。)

つまり,先に 「外部テキストのロード」 書いてしまった場合は,

 LoadVarsインスタンスが作成される
   ↓
 外部テキストのロードが開始される
   ↓0 秒で
 外部テキストのロードが完了する
   ↓
 LoadVars.onLoad が定義される
 (定義しても意味ナシ)


となる可能性もないとは言いきれませんよね。
ということです。


~~~ ~~~ ~~~ ~~~ ~~~ ~~~

次のようにスクリプトをバラせば理解できるのではないかと思います。

お手数ですが新規ドキュメントを作成して,
ステージ上に塗りの入った矩形(長方形)を,適当に左右に2つ並べて用意してみてください。


  ■■■■    □□□□
  ■■■■    □□□□
  左の矩形    右の矩形

その2つの矩形を別々の「ボタンシンボル」に変換します。
(ムービークリップでもグラフィックでもなくボタンシンボルに変換します。)

  ■■■■    □□□□
  ■■■■    □□□□
  左のボタン    右のボタン


そして,まず フレーム に次のように書いておきます。

-----------------------------------
var textReaderLV:LoadVars = new LoadVars();
// LoadVarsクラスのインスタンスを作成。
-----------------------------------

これで,textReaderLV というインスタンス名の LoadVarsインスタンスが作成されることになります。

そして,
左のボタン 自体には次のように書きます。

-----------------------------------
on (release) {
textReaderLV.onLoad = function() {
// ロード処理が完了したときの動作定義
trace("「hoge」の値は,"+textReaderLV.hoge);
};
}
-----------------------------------

この 左のボタン をクリックしたときに,
ロード処理が完了したときの動作が定義されます。
そして,
右のボタン 自体には次のように書きます。

-----------------------------------
on (release) {
textReaderLV.load("data.txt");
//外部テキスト"data.txt" を読み込み。
}
-----------------------------------

この 右のボタン をクリックしたときにはじめて,
外部テキストである 「data.txt」 の読み込みが開始されます。


この状態で,
「制御」→「ムービープレビュー」をします。
「右のボタン」クリック→「左のボタン」クリック という順にクリックしても,

 「hoge」の値は,○○○

は出力されないと思います。
「右のボタン」クリックで外部テキストがロード開始され,
「左のボタン」クリックでロード処理完了時の動作定義が行われるころには,
すでにロード処理は完了しているからです。

この状態で,次に再び 「右のボタン」 をクリックすると,

 「hoge」の値は,○○○

が出力されるはずです。
「左のボタン」クリックでロード処理が完了したときの動作が定義されているので,
「右のボタン」クリックでロードが開始され,ロード処理が完了したときに,
trace("「hoge」の値は,"+textReaderLV.hoge); が実行されるからです。

『「hoge」の値は,○○○』 の ○○○ には実際に何が表示されるのかは知りません。
「data.txt」 が用意してあって,その内容に hoge=▲▲▲ というデータが用意されていれば,
『「hoge」の値は,▲▲▲』 となるでしょうし,用意されていなければ,『「hoge」の値は,undefined』 となるでしょう。


その「ムービープレビュー」画面をいったん閉じて,
再び 「制御」→「ムービープレビュー」をします。
今度は,
「左のボタン」クリック→「右のボタン」クリック という順にクリックすると,
「右のボタン」をクリックしたとき,普通に 『「hoge」の値は,○○○』 が出力されるはずです。


「左のボタン」クリック→「右のボタン」クリック という順にボタンがクリックされなければなりません。
「右のボタン」クリック→「左のボタン」クリック という順にボタンがクリックされるとまずいということになります。
プログラム的に言いなおせば,
「外部テキストロード処理完了」→「ロード処理完了時の動作を定義」となったらまずいわけです。

つまり,0 秒でロードが完了してしまったなら,
textReaderLV.onLoad = function() {○○}; の ○○ は実行されないかもしれませんよ。
ということになります。



~~~ ~~~ ~~~ ~~~ ~~~ ~~~

> (データロードが完了しなければ、処理が実行されないのでは?
> とも思うのですが、実際そうではないので
> この辺りに私の誤解があるのかもと思ったり)

「data.txt」があってもなくても,
textReaderLV.load("data.txt"); が実行されれば,
textReaderLV.onLoad = function() {○○}; の ○○ は実行されます。

LoadVars.onLoad はロード処理が完了したときに呼びだされます。
「data.txt」があってもなくても,つまり,ロードが成功しても失敗ししても,そんなことは関係なく,
「ロード処理が完了」時点で呼びだされます。

おそらく,
「data.txt」がなかった場合,サーバもしくはローカルPCから,
「そんなファイルはないよ!」 という内容のエラーメッセージがFlash側に返されるのだと思います。
つまり,「そんなファイルはないよ!」 という内容のエラーメッセージを textReaderLV がロードするのだと思います。
存在する「data.txt」のデータであっても,「そんなファイルはないよ!」 という内容のエラーメッセージであっても,
とにかく textReaderLV のロード処理は完了するので,
そのときに textReaderLV.onLoad = function() {○○}; の ○○ は実行されます。

「ロードが成功したとき」 と 「ロードが失敗したとき」 とで別々の動作をさせたい場合は,
#2 で書いた URL のページにも書いていますように,

textReaderLV.onLoad = function(適当な変数:Boolean) {
if (適当な変数) {
// ここにロード成功時の動作を書く
} else {
// ここにロード失敗時の動作を書く
}
};

のようにして分岐させてください。

しかしこの,ロード成功 or ロード失敗 は,ご質問の本題とは関係がないことです。
すべてを一緒くたに考えると混乱の元となりますので,全く別物として考える方が良いと思います。
    • good
    • 0
この回答へのお礼

BlurFiltanさん、再度のご回答ありがとうございます。

長文で詳細なご回答をいただき、バッチリ理解できました(^0^。
ここまで詳細にご回答いただくとなんだか申し訳ないと思えてくるぐらいです。

大変大変参考になりました。
ありがとうございました。

お礼日時:2007/08/09 00:29

以下 ヘルプからの参照


LoadVars.onLoad
シンタックス
my_lv.onLoad = function(success:Boolean) {
// ここにステートメントを記述【A】
}
パラメータ
success ロード処理が正常に完了したか (true) または失敗したか (false) を示すブール値。
//----------------------------------
【A】には
success=true の時の、Load完了時の処理と
success=false の時の、Load失敗時の処理を
記述する訳ですね。
つまり、onLoadは
「Load」処理が完了したかどうかを見てるので、「Load」が終わった後に設定しても無意味ですよね?

と、いうことではどうでしょうか?
    • good
    • 0
この回答へのお礼

kuri627さん、書き込みありがとうございます。

参考にさせていただいております。
ありがとうございました。

お礼日時:2007/08/09 00:30

#1です。


もののたとえ方が間違っていました。訂正いたします。

> その定義自体が空振りになる可能性も考えられます。
→その定義自体が見送りになる可能性も考えられます。

バッターボックスにバッターが立つ前に,ピッチャーからボールを投げられてしまった場合,
用意ができていないバッターはボールを見送ってしまう。

ということをイメージして書いたつもりが,
「空振り」という的を射ていない比喩になってしまっていました。

言いたいことは同じなのですが,
私の妙な説明より,次のページの方がわかりやすいと思います。

「LoadVarsオブジェクトを使った外部テキストファイルの読込み」
http://www.fumiononaka.com/TechNotes/Flash/FN030 …
このページの下の方より引用
> LoadVars.onLoadメソッドの定義について、
> ひとつ大事な注意があります。
> LoadVars.loadメソッドによる外部テキストファイルのロードを
> LoadVars.onLoadメソッドの定義より先に実行してしまうと、
> 定義が済む前にロードが完了してしまうおそれがあります。
> すると、定義が有効になったときには、
> もはやonLoadの呼出しが終わっているので、
> イベントハンドラメソッドは実行されないことになります。
> ですから、LoadVars.onLoadメソッドの定義をまず行ってから、
> LoadVars.loadを実行するのが確実です。
    • good
    • 0
この回答へのお礼

BlurFiltanさん、書き込みありがとうございます。

詳細にご説明いただきながら、まだ上手く理解ができない状態です(というより私は他の部分で勘違いして理解しているようなのですが、、、)。
まず私の理解(勘違い?)として、すべてコードは上から順に処理が進み、その処理が終わると次の行へ進むという理解なのですが、どうもここの辺りで私の勘違いがあるようなのですが、
例えば、

var textReaderLV:LoadVars = new LoadVars();
// LoadVarsクラスのインスタンスを作成。

textReaderLV.load("data.txt");
//外部テキスト"data.txt" を読み込み。

textReaderLV.onLoad = function() {
trace("「hoge」の値は," + textReaderLV.hoge);
};
// データのロードが完了したら、function() を実行。(データロードが完了しなければ、処理が実行されないのでは?とも思うのですが、実際そうではないのでこの辺りに私の誤解があるのかもと思ったり)

と理解しています。(というより上記は2と3を逆に書いていますので、本来の例題が私のような理解の仕方だと成立しないのですが、、、)

上記のような理解ですと、どこかに何らかの誤解をしているものと思うのですが、よろしければその点をご指摘いただけないでしょうか。
お時間などありましたらまた書き込みをいただけたらと思います。
よろしくお願いします。

お礼日時:2007/08/06 21:21

テキストの読み込みには多少時間がかかるので,どちらでも良いと思います。


しかし,テキストが本当に 0 秒で読み込まれてしまった場合はどうなるでしょう?

LoadVarsインスタンスの作成
  ↓
外部テキストの読み込み(0秒)
  ↓
外部テキスト読み込み時の動作を定義

外部テキストが読み込まれてしまったあとに,
テキスト読み込み時の動作定義を Flash が認識した場合,
その定義自体が空振りになる可能性も考えられます。

普通の場合はそうならないのですが,
確率,可能性,論理順 から考えると,

LoadVarsインスタンスの作成
  ↓
外部テキスト読み込み時の動作を定義
  ↓
外部テキストの読み込み

とする方が無難です。

これに限らず,

変数などの定義や作成
  ↓
関数の定義
  ↓
関数の実行

と書いているものが多いと思いますよ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!