複数の非同期処理の完了を通知するQueueクラス
複数のファイルを読み込む場合など、複数の非同期処理の進行状況とすべてが完了したタイミングをイベントとして受け取ることができるQueueクラスを公開しました。
サンプルのダウンロードはこちらから。
クラスを公開するというほど大げさなものではありませんが、なるべく標準的なイベントモデルには変更を加えずに、複数イベントの完了を通知することができます。
仕組みはいたって単純で、各イベントを受け取るリスナーを Queue(待ち行列)に追加し、イベントが呼ばれたらQueueから削除しているだけです。
Queueが削除されたタイミングとQueueがなくなったタイミングでイベントが発生し、
queue.length / queue.totalで進行状況を知ることができます。
また、エラー発生時にもリスナーをQueueから削除するようにしておけば、ファイルが一部取得できなかった場合にもQueueの完了イベントを受け取ることができます。
以下は、3つのテキストファイルを読み込んで、3つすべてが読みまれたらすべてのファイルの内容をtraceするサンプルです。いずれかのファイルが取得できなかった場合も、Queue.COMPLETEイベントが発生します。
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import org.as3s.Queue;
public class QueueSample extends Sprite {
private var queue:Queue;
private var loaderList:Array;
public function QueueSample() {
loaderList = new Array();
//Queueの作成
queue = new Queue();
queue.addEventListener(Queue.PROGRESS, onProgress);
queue.addEventListener(Queue.COMPLETE, onComplete);
var loader:URLLoader;
for (var i:int=0; i<3; i++) {
loader = new URLLoader();
loaderList[i] = loader;
try {
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
queue.put(onLoadComplete); //Queueに追加
loader.load(new URLRequest("data/test"+i+".txt"));
} catch (error:Error) {
trace("Unable to load requested document.");
queue.get(onLoadComplete); //Queueから削除
}
}
}
private function onLoadComplete(event:Event):void {
trace("LoadComplete");
queue.get(onLoadComplete); //Queueから削除
}
private function onLoadIOError(event:Event):void {
trace("IOError");
queue.get(onLoadComplete); //Queueから削除
}
//Queueの進行状況を通知
private function onProgress(event:Event):void {
trace("Progress: "+(queue.total-queue.length)+"/"+queue.total);
}
//Queueの完了を通知
private function onComplete(event:Event):void {
trace("Complete");
for each (var loader:URLLoader in loaderList) {
trace(loader.data);
}
queue.removeEventListener(Queue.COMPLETE, onComplete);
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import org.as3s.Queue;
public class QueueSample extends Sprite {
private var queue:Queue;
private var loaderList:Array;
public function QueueSample() {
loaderList = new Array();
//Queueの作成
queue = new Queue();
queue.addEventListener(Queue.PROGRESS, onProgress);
queue.addEventListener(Queue.COMPLETE, onComplete);
var loader:URLLoader;
for (var i:int=0; i<3; i++) {
loader = new URLLoader();
loaderList[i] = loader;
try {
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
queue.put(onLoadComplete); //Queueに追加
loader.load(new URLRequest("data/test"+i+".txt"));
} catch (error:Error) {
trace("Unable to load requested document.");
queue.get(onLoadComplete); //Queueから削除
}
}
}
private function onLoadComplete(event:Event):void {
trace("LoadComplete");
queue.get(onLoadComplete); //Queueから削除
}
private function onLoadIOError(event:Event):void {
trace("IOError");
queue.get(onLoadComplete); //Queueから削除
}
//Queueの進行状況を通知
private function onProgress(event:Event):void {
trace("Progress: "+(queue.total-queue.length)+"/"+queue.total);
}
//Queueの完了を通知
private function onComplete(event:Event):void {
trace("Complete");
for each (var loader:URLLoader in loaderList) {
trace(loader.data);
}
queue.removeEventListener(Queue.COMPLETE, onComplete);
}
}
}
▼出力結果
LoadComplete
Progress: 1/3
LoadComplete
Progress: 2/3
LoadComplete
Progress: 3/3
Complete
This is Test0.
This is Test1.
This is Test2.