どうも非同期処理というのはめんどくさい。
そして、やはり、ちょっと考え方にくせがある。
今回は、そんな例の1つ。
同期型関数、つまり、すぐに値を戻す必要がある関数の中で、
非同期処理を行って値を返さなければならない場合にはどうしたらいいの?
というお話。
この説明だけでは???がいっぱいだと思う。
基本的には非同期型関数を使っている場合には、結果が取得できてから、その後の処理を行っていくに方がいいのだが、
あれは同期型関数で、これは非同期型関数と決まってしまっている中でどうにもならないということも。
そうすると、どうもこのような矛盾したことを言いたくなってしまう。
まずは、サンプル。
やっている事は、get labelというボタンを押すとすぐに、
[please wait 2 seconds ...]
という文字が出力されます。
この文字は、同期型関数として返している値です。
その約2秒後に本当のデータである、
[--done--]
という文字が返ってきます。
全体のソースはサンプルの右クリックから参照してほしいのですが、
ボタンが押されると動く関数を抜粋しますと
protected function get_item(index:int):Object{
var item:Item = new Item();
item.label = " please wait 2 seconds ... ";
var objectProxy:ObjectProxy = new ObjectProxy(item);
// 何らかの非同期処理
// 擬似的に2秒後に実行する処理で代用
var func:Function = function():void{
// 本来の値を設定する
objectProxy.label = "--done--";
// 変更があったことをCollectionに知らせるイベントを発行する
var evt:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
evt.kind = CollectionEventKind.REPLACE;
evt.location = index;
list.dispatchEvent(evt);
};
setTimeout(func,2000);
return objectProxy;
}
このように、本当に返したいオブジェクトを ObjectProxyクラスのオブジェクトでラップしてしまいます。
ここでは、サンプルの為のサンプルとしてのsetTimeoutですが、実際にはここでネットワークを通してデータを取得したり、
私の場合には非同期処理としてのsqliteとしてのデータ取得だったりします。
そして、その非同期処理の中でデータを取得できたら、データが変わったことを通知するイベントをCollectionListの方へ伝えます。
そして、そのデータ群を表示する画面制御はそのイベントを受けて、画面をリフレッシュしていくという訳です。


