2012-04-30 5 views
0

Flex/ActionScriptで非同期シーケンスに問題があります。ここで は一例です:ActionScript 3.0のメソッドシーケンスの強制

private function start():void{ 
    _menu = new MyMenu(); 
    _screen.addElement(_menu); 
    //Here, some Mouse Event Listener to Menu Click 
} 

さて、メニューのクリックが発生したと仮定しましょう。

private function menuClick(event:Event):void{ 
    removeMenu(); 
    addMenu(event.SomethingPassedByTheClick); 
} 

ここで、イベントハンドラの問題について忘れて、プロセスについて考えてみましょう。 私の問題は、エラーにつながるremoveMenu()の前にaddMenu()が終了することがあることです。 上記のスクリプトは、実際のスクリプトではなく、私の問題を論理的に表現したものです。 sunupするには、addMenu()メソッドが呼び出される前にremoveMenu()が完了するのを待つことを定義する必要があります。何かご意見は? ご協力いただきありがとうございます。

編集:

私の問題のより正確な例:

private function createComplete():void{ 
     _screenArray = new Array(
       new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
       new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
       new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 
     startUp(); 
} 

private function startUp():void{ 
    //Some mathematical calculations that changes a few 0 to 1's. 
    addNewComponent(); 
} 

private function addNewComponent():void{ 
    removeAllComponents(); 
    //More calculus on the array in order to create a component in vague space. 
    addComponentOnCalculatedArea(x, y); 
    //here is my problem: Sometimes, add Method is called before the removeAllComponents, which causes the new added component be removed by the removeAllComponents() method. 
} 

みんなありがとう。私は間違った前提を持っていた。何が間違っていた私の数学は、メソッドの順序ではなく、計算されます。私は、Scriptの各メソッドにtrace()を追加することで気づいた。

+1

独立したサンプルアプリケーションを投稿することはできますか?私はそこに真ん中に何かが入り込むことができないので、私がここに完全に従っているかどうかはわかりません。考えてみると、removedAllComponentsの後に無限ループwhileループを置いて何も実行されないことに気づく – devshorts

+1

'removeAllComponents'メソッドが非同期で実行されない限り、' removeComponentOnCalculatedArea'は 'removeAllComponents'の実行が完了するまで起動できません。いくつかトレースを展開するか、デバッガで実際に何が起きているかを確認する必要があります。 – shanethehat

+0

何が間違っているのかを知るには、 'removeAllComponents()'と 'addNewComponent()'のコードを見る必要があります。また、おそらく 'addComponentOnCalculatedArea()'。 – iND

答えて

1

いつ利用可能かを知るには、コンポーネントのライフサイクルをヒンジする必要があります。メニューオブジェクトのcreationCompleteイベントが発生するまでマウスイベントを追加しないでください。

イベントに左右されない場合は、多くの非同期問題が発生します。これは非同期アプリケーションの基礎です!

さらに、処理が完了したらフラグを設定する必要があります。これらの線に沿って

private function start():void{ 
    _menu = new MyMenu(); 
    _menu.addEventListener(FlexEvent.CREATION_COMPLETE, eventHandler); 
    _screen.addElement(_menu); 
} 

private function eventHandler(...rest):void{ 
    _menuCreated = true; 
    _menu.removeEventListener(FlexEvent.CREATION_COMPLETE, eventHandler); 
} 

private function menuClick(event:Event):void{ 
    if(!_menuCreated){ 
     return; 
    } 

    removeMenu(); 
    addMenu(event.SomethingPassedByTheClick); 
} 

何か:それはremoveMenuがaddMenu前に評価できるようにすることはありませんすることが重要である場合は、このような何かをやるべき終了します。

また、RemoveMenuを待っているAddMenuについて説明しました。 as3は非同期ですが、シングルスレッドでもあります。同時に複数の機能を評価する必要はありません。 RemoveMenusが実行されているとき、AddMenuは実行されません。

この明確には、我々はこれを行うはずができますようにするには:

private function doFirst():void{ 
     trace("first"); 
    } 

    private function doSecond():void{ 
     trace("second"); 
    } 

    private function doThings():void{ 
     doFirst(); 
     doSecond(); 
    } 

この例では、それは常に「最初」あなたは関係なくdoFirstにかかる時間doThingsを呼び出していないならば、「第二」を印刷します。 doFirstに無限ループwhileループがある場合、フロー制御が中断されることはありません。アプリケーション全体が停止します。今

doFirst()は、いくつかのイベントを送出し、asynchornouslyそれが派遣物事がdoFirst機能の仕上げdoSecond後に起こることはできませんが、物事を行うために必要がある場合。その場合はdoFirstのすべての作業が完了した後にdoSecondのイベントリスナーを登録する必要があります。

私が言及したように、必要な作業のイベントハンドラにフラグを設定してから、コンポーネントのプロパティを無効にすることができます。これによりcommitPropertiesが呼び出され、次の項目を実行できます。

コンポーネントの非同期ライフサイクルを説明するリンクであるhttp://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_3.htmlおよびhttp://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html#commitProperties()をチェックし、プロパティを非同期に設定する方法を調べます。

+0

メニューがまだ作成されていない場合はクリックを生成することができないので、そうではありません。私の問題は、最初のメニューがすでに作成された後に起こります。最初のものを削除して2番目のものを作成したいときは、最初に削除する順番にしておき、その後に別のものを追加します。 シングルスレッドについては、わかっています。しかし、非同期的な理由から、addMenu()がremoveMenus()の前で実行されることがあります。 –

+0

メニューをどのように削除しますか?あなたはそれを親コンポーネントの子リストから削除していますか?これはポップアップですか?いくつかのサンプルコードは、より良い答えを与えるのに役立ちます – devshorts

+0

あなたのコードでaddMenuはremoveMenuを非同期に他のイベントで削除することによってremoveMenuを終了させない限り終了します。その場合は、完了したすべてのイベントを聴いてそのように同期させるためにaddMenuをヒンジする必要があります。 – devshorts

1

私はdevshorts'答えに同意するが、最終的な機能には私もコールバックを追加します。

private function menuClick(event:Event):void{ 
    if(!_menuCreated){ 
     return; 
    } 
    removeMenu.addlistener(someCompleteEvent, menuRemoved); // Don't add until you are sure. 
} 

private function menuRemoved (SomethingPassedByTheClick: ClickEvent): void{ 
    addMenu(event.SomethingPassedByTheClick); 
} 

これは、メニューの除去の前に新しいメニューを追加することに完了したことを確認するために役立つだろう。