关于Actionscript3的事件驱动代码执行机制

本文通过两个测试场景探讨了Flash中事件处理的执行顺序及函数执行的原子性特点,揭示了Flash代码执行线程的单一性及其事件驱动的本质。
近来写代码的时候,常常会担心代码的执行顺序,例如某个函数是否会被事件处理函数打断之类的,百度了一下,无果(这个已经早就预料到的了),关键时候还是得翻出我的英语老底,投靠google吧。

以下是我自己设计的测试场景:

[b][size=medium][color=brown]测试场景1:[/color][/size][/b]
假设有类ExecutionTest, 代码如下:

package com.longpeijin.exec
{
import flash.display.Sprite;
import flash.events.Event;

public class ExecutionTest extends Sprite
{
public function ExecutionTest()
{
var obj:SystemHandler = new SystemHandler(this,"1");
var obj1:SystemHandler = new SystemHandler(this,"2");
this.dispatchEvent(new Event(SystemHandler.SYS_EVENT));
trace("Main function executed!");
}
}
}


和另外一个类SystemHandler:

package com.longpeijin.exec
{
import flash.events.Event;
import flash.events.EventDispatcher;

public class SystemHandler
{
public static const SYS_EVENT:String = "sysEvent";
private var name:String;

public function SystemHandler(obj:EventDispatcher, name:String)
{
obj.addEventListener(SYS_EVENT,onEvent);
this.name = name;
}

public function onEvent(event:Event):void{
trace("event handler executed! " + name);
}
}
}


简单来说就是ExecutionTest类的某个方法在执行的过程中发布了一次事件,紧接着其后又执行了一些代码,那么监听这个事件的事件处理程序会马上执行还是等待ExecutionTest执行完毕才执行呢?

输出结果如下:

event handler executed! 1
event handler executed! 2
Main function executed!


结果可以知道,在执行过程中发布一次时间,其实就是在事件监听链条上逐个执行事件处理程序,然后再返回主函数,跟普通的函数调用没有两样!

所以ExecutionTest类的构造函数等价于以下的样子:

package com.longpeijin.exec
{
import flash.display.Sprite;
import flash.events.Event;

public class ExecutionTest extends Sprite
{
public function ExecutionTest()
{
var obj:SystemHandler = new SystemHandler(this,"1");
var obj1:SystemHandler = new SystemHandler(this,"2");
obj.onEvent(null);
obj1.onEvent(null);
trace("Main function executed!");
}
}
}


[b][size=medium][color=brown]测试场景2:[/color][/size][/b]

另外一个我想知道的问题就是,假如有一个函数正在执行一个比较耗时的操作,这时候其他的一个对象发出了一次事件(例如一个网络资源下载完成了),而自身也有监听这个事件,那么这时当前函数的执行会被打断么?

于是我设计了以下的类EventTest:

package com.longpeijin.event
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.net.URLRequest;

public class EventTest extends MovieClip
{
public function EventTest()
{
super();
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("http://www.evolife.cn/wp-content/uploads/2010/06/iphone4display3.jpg"));
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
this.stage.frameRate = 20;
}



private function onEnterFrame(event:Event):void{
trace("On Enter frame start!");
//do something time consuming
var arr:Array = [];
for(var i:int;i<10000;i++){
arr.push(Math.random());
}
for each(var num:int in arr){
Math.sqrt(num*100);
}
trace("On Enter frame end!");
}

private function onComplete(event:Event):void{
trace("Resouces loaded!");
}
}
}


为了排除网络速度因素,我执行了该类10次,但每次的输出都有一个固定的片段:

On Enter frame start!
On Enter frame end!
Resouces loaded!
On Enter frame start!
On Enter frame end!

Resouces loaded!没有一次出现在On Enter frame start!和On Enter frame end!之间,换句话说,函数从来没有被打断过。

[size=medium][color=blue]之前也求教过一些高手,得知Flash的代码执行线程只有一个(这里指的是执行代码的线程,不包括下载网络资源的那些线程),有点类似底层CPU的时间片轮转执行,但轮转的并不是线程(因为主线程只有一个),而是各个对象的事件处理函数(Timer事件,Event.Complete事件,KeyboardEvent之类的),所以AVM的执行完全是事件驱动的。即使主MovieClip的构造函数(类似于Java中的main方法)执行完毕,程序不会像普通Java程序那样直接退出,而是空闲着等待着事件的发生,而且函数的执行是原子性的,任何时候不会被打断(除非AVM被崩掉或者你叉掉浏览器啦)。
换个角度来看Flash是不支持多线程的,所以6核、双核、单核的CPU执行起来,都只会用到其中的一个核心而已。[/color][/size]
上面的探讨如有任何错误或疑惑,欢迎回复指正和讨论。
内容概要:本文详细介绍了一种基于Simulink的表贴式永磁同步电机(SPMSM)有限控制集模型预测电流控制(FCS-MPCC)仿真系统。通过构建PMSM数学模型、坐标变换、MPC控制器、SVPWM调制等模块,了对电机定子电流的高精度跟踪控制,具备快速动态响应和低稳态误差的特点。文中提供了完整的仿真建模步骤、关键参数设置、核心MATLAB函数代码及仿真结果分析,涵盖转速、电流、转矩和三相电流波形,验证了MPC控制策略在动态性能、稳态精度和抗负载扰动方面的优越性,并提出了参数自整定、加权代价函数、模型预测转矩控制和弱磁扩速等优化方向。; 适合人群:自动化、电气工程及其相关专业本科生、研究生,以及从事电机控制算法研究与仿真的工程技术人员;具备一定的电机原理、自动控制理论和Simulink仿真基础者更佳; 使用场景及目标:①用于永磁同步电机模型预测控制的教学演示、课程设计或毕业设计项目;②作为电机先进控制算法(如MPC、MPTC)的仿真验证平台;③支撑科研中对控制性能优化(如动态响应、抗干扰能力)的研究需求; 阅读建议:建议读者结合Simulink环境动手搭建模型,深入理解各模块间的信号流向与控制逻辑,重点掌握预测模型构建、代价函数设计与开关状态选择机制,并可通过修改电机参数或控制策略进行拓展验,以增强践与创新能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值