我一直在努力了解ActionScript事件的实现方式,但我陷入困境。
我知道AS是单线程的,这意味着一次只能执行一个事件处理程序,这也意味着处理程序将以确定的顺序执行*。
例如,请考虑以下代码:
1: var x = {executed: false};
2: foo.addEventListener("execute", function(){ x.executed = true; });
3: foo.dispatchEvent(new Event("execute"));
4: assert(x.executed);
如果ActionScript是多线程的,那么第4行的断言有时可能会失败并成为其他人。
但由于AS不是多线程的,因此断言将始终失败²或始终成功³。或者,换句话说,事件将以确定的方式处理。
那么,这个假设(确定性地处理事件)是否正确? Adobe是否就此事提供了任何明确的文件?
注意:我仅关注dispatchEvent
调度的事件 - 我意识到“外部调度”事件(网络流量,用户输入,定时器滴答等)表现不同。
*:当然,例外情况是由用户输入或网络流量等非确定性事件触发的事件。
²:例如,如果事件处理算法是:“将新事件推送到堆栈,然后不断地从堆栈中弹出顶级事件,执行它直到它终止,然后继续下一个事件”,它总是会失败。
³:如果dispatchEvent
发出的事件在发送后立即处理,它总是会成功。
答案 0 :(得分:7)
除非我误解 - 在这种情况下,我道歉! - 我不同意其他人:你只需要测试你提交的代码,每次都看到x.executed trace的值是真的。
例如,如果代替你的foo对象,你要替换IEventDispatcher(在这种情况下我是隐式地使用我的app对象及其creationComplete处理程序),你会看到:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
private function onCreationComplete():void
{
var x = {executed: false};
addEventListener("execute", function() { x.executed = true; });
trace(x.executed); // false
dispatchEvent(new Event("execute"));
trace(x.executed); // true
}
]]>
</mx:Script>
</mx:WindowedApplication>
当然,有一些方法可以控制事件处理 order (使用addEventListener的优先级参数),以及显示列表中对象的各种事件传播阶段(例如,捕获,定位,冒泡 - 请参阅Flex文档以获取详细信息here和here),但在这种情况下,事件确实基本上按内联和优先级顺序处理。根据文件:
Flex在中注册事件监听器 addEventListener()的顺序 方法被称为。然后Flex调用 事件时监听器的功能 按照它们的顺序发生 注册。但是,如果您注册 一些事件监听器内联和一些 使用addEventListener()方法, 听众的顺序 要求单个事件可以 不可预测的。
希望有所帮助!
答案 1 :(得分:-2)
第4行将始终在事件处理程序之前执行,因此执行将始终断言为false。函数完成后,处理程序将执行。
你是第2点是正确看待它的方法。