0

Flex/ActionScript の非同期シーケンスに問題があります。次に例を示します。

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);
}

さて、イベント ハンドラのエラーのことは忘れて、プロセスについて考えてみましょう。私の問題は、 addMenu() が removeMenu() の前に終了することがあり、エラーが発生することです。上記のスクリプトは、実際のスクリプトではなく、私の問題を論理的に表現したものです。まず、メソッド 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.
}

みんな、ありがとう。前提が間違っていました。呼び出されるメソッドの順序ではなく、私の数学の計算が間違っていたのは何ですか。スクリプトの各メソッドに trace() を追加することで気づきました。

4

2 に答える 2

1

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

イベントに依存しないと、多くの非同期の問題が発生します。これが非同期アプリケーションの基本です。

その上で、物事が達成されたときにフラグを設定する必要があります。addMenu が終了する前に removeMenu が評価されないようにすることが重要な場合は、次のようにする必要があります。

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 についても言及しました。as3 は非同期ですが、シングル スレッドでもあります。複数の関数が同時に評価されることはありません。RemoveMenus が実行されている場合、AddMenu は実行されません。

これをより明確にするために、次のようにするとします。

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

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

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

doThingsこの例では、どれだけ時間がかかっても、呼び出すと常に「最初」、次に「2番目」と出力されdoFirstます。無限 while ループがフロー制御を中断しない場合doFirst、アプリケーション全体が停止します。

いくつかのイベントをディスパッチし、非同期で処理する必要がある場合、doFirst()ディスパッチする処理doSecondは関数の終了後に発生する可能性がありdoFirstます。その場合はdoSecond、すべての作業doFirstが完了した後に起動するイベント リスナーを登録する必要があります。

前述したように、実行する必要がある作業のイベント ハンドラーにフラグを設定してから、コンポーネントのプロパティを無効にすることができます。これが呼び出さ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 () は、コンポーネントの非同期ライフサイクルと、非同期でプロパティを設定する方法を説明するリンクです。

于 2012-04-30T22:01:30.680 に答える
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);
}

これは、新しいメニューを追加する前に、メニューの削除が完了したことを確認するのに役立ちます。

于 2012-04-30T22:16:06.490 に答える