2011-01-28 11 views
0

以前に複数のリモートオブジェクト呼び出しを並列に実行していて、それらをシリアルで実行させようとしています。Actionscriptでのシンプルなイベントチェーニング。ディスプレイを強制的にリフレッシュさせるには

私はそれがハックアプローチ(バンドエイド!)だけど、これまでのところ、私のアプローチは、forループの各並列要求を開始これを取るようにされています:

(オリジナルコード)

for (i = 0; i < _processQ.length; i++){ 
fObj = _processQ.getItemAt(i); 
f = fObj.Name; 
fObj.Progress = "Processing..."; 
ro.process(gameid,f); 
} 

と、このように変更します。

(新コード)

for (i = 0; i < _processQ.length; i++){ 
fObj = _processQ.getItemAt(i); 
f = fObj.Name; 
fObj.Progress = "Processing..."; 
ro.process(gameid,f); 

//pause this loop until a result is returned from the request that was just made. 
_pause_queue = true; 
while(_pause_queue){ 
    //do nothing 
} 
} 

ここで、_pause_queueは、クラスのプライベートグローバルブール値です。 fault-handlerおよびresponse-handler関数では、それはfalseに戻され、無限のwhere-loopが解放され、forループが続行されます。

これは機能しますが、UIはwhileループの終了後にのみ更新されるため、応答を待つ間にアプリケーションがハングアップするような負の副作用が発生します。

フラッシュにディスプレイを更新させるためにwhileループの中に入れることができるものはありますか? VBでは(ugh!)私はDoEventsを使用しますが、私はActionscriptに相当するものはわかりません。

代わりに、アプリケーションを書き換える完全のシンプルキューイングシステムのショートを追加する方法はありますか?これは旧式のコードなので、締め切りが早いので、できるだけ少し修正したいと思います。 (さもなければ、私はそれを最初から書き直してSwizを使ってイベントチェーンを取得します)

答えて

2

代わりに、 は完全にアプリケーションを書き換えるの短い シンプルなキューイング・システムを追加する方法はありますか?

はい、配列を使用できます。すでに_processQ変数を持っているようです。

// A process queue item method 
protected function processItemInQueue():Void{ 
if(_processQ.length > 0){ 
    fObj = _processQ.pop(); 
    f = fObj.Name; 
    fObj.Progress = "Processing..."; 
    ro.process(gameid,f); 
} 
} 

は、その後、あなたのリモートオブジェクトの結果ハンドラに:

protected function roResultHandler(event:ResultEvent):void{ 
// process results 

// process next item in queue 
processItemInQueue(); 
} 
+0

+1。 whileループのどのタイプよりも優れています。Flexの非同期性を取り入れています。それを愛するには時間がかかりますが、本当に優れています...アイテムの数が分かっていれば、次のようなことができるような流暢な非同期関数連鎖を書くことを検討するかもしれません: 'executeProcess(proc1、handler1).executeProcess (proc2、handler2).executeProcess(proc3、handler3).Go() 'これは同じようなことですが、より表現力があります。 –

+0

ありがとう、私はこれに似た何かをするつもりです。 –

1

ActionScriptはシングルスレッドなので、whileループは本当に永遠にハングします。考慮すべき点は、Timerクラスを使用してイベントを定期的に発生させたり、各フレームの開始時に起動するENTER_FRAME(flash playerはfpsドメイン内で考える)にイベントリスナーを追加することです。

ro.process()がリモートIO操作(Webページの取得またはWebサービス呼び出しの呼び出し)でない限り、作業中にUIをハングします。あなたは仕事を分けて、一度にすべてではなくすべてのフレームを発射したいと思うかもしれません。また、グローバル変数とループを設定する代わりに、EventDispatcherロジックを使用して終了時やフォルトを聴く方法も学習する必要があります。

+0

-1 Flash Playerがシングルスレッドではありません私はこのような何かを試してみてください。そうであれば、複数のリモートリクエストを並行して実行することはできません。彼は2番目に消える前に1人が終わるのを待たなければならなかった。プログラマが個々のスレッドを作成するためのAPIをFlash Playerが提供していないと言うのは事実です。 – JeffryHouser

+0

私はActionScript自体を意味するわけではありません。 http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.htmlをお読みください "Actionscriptはシングルスレッドなので、計算時間が多すぎるとUIが更新されませんその計算を実行しているため、アプリケーションが停止したり、エフェクトが円滑に実行されません。 –

+0

私はまた、フレックスが私の元の答えで非ブロッキングリモートI/Oを可能にすることを述べました。 –

0

1つのループですべてをやろうとするのではなく、すべてのイベントにするのはなぜですか?

優先度つきキューについては
function outerFunction() { 
    var queue = new SomeAsyncProcessor(); 

    for (i = 0; i < _processQ.length; i++){ 
     queue.addProcess(_processQ.getItemAt(i)); 
    } 

    queue.addEventListener('complete', handleProcess); 
    queue.start(); 

    game.pause(); 
} 

function handleProcess(event) { 

    var processor = event.currentTarget as SomeAsyncProcessor(); 
    process.removeEventListener('complete', unpause); 

    game.unpause(); 
} 

- あなたはこれを使用することができます

http://www.polygonal.de/legacy/as3ds/doc/de/polygonal/ds/PriorityQueue.html

主にちょうどあなたが一つの大きなイベントに現在持っているものラップ、同様に1を書き込むための、あまりにも多くの時間べきではありませんディスパッチャ(現在のプロセッサがすでにイベントを送出している限り)。

+0

私は解決策としてキューを使用するというアイデアが気に入っていますが、コードが実際にそれをどのように達成しているか理解していません。 – JeffryHouser

関連する問題