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在此示例中,无论需要多长时间,如果您调用,它总是会打印“first”然后是“second” doFirst。如果doFirst有一个无限的while循环,没有什么会破坏它的流控制,它会停止整个应用程序。

现在,如果doFirst()调度一些事件并且需要异步执行某些事情,那么它调度的事情可能会在函数doSecond完成之后发生,但不会发生。doFirst如果是这种情况,您应该注册一个事件侦听器,doSecond以便在所有工作doFirst完成后触发。

就像我还提到的那样,您可以在需要执行的工作的事件处理程序中设置标志,然后您可以使组件的属性无效。这将调用commitProperties,您可以在那里执行下一个项目。

检查http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_3.htmlhttp://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 回答