包 | flash.system |
类 | public final class MessageChannel |
继承 | MessageChannel EventDispatcher Object |
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
每个 MessageChannel 对象都包含从发送 worker 发送到接收 worker 的一个消息对象队列。对 send()
的每次调用都会向该队列中添加一个对象。对 receive()
的每次调用都从该队列中检索最早的消息对象。
不要通过调用 MessageChannel()
构造函数来直接创建 MessageChannel 实例。要创建 MessageChannel 实例,请调用将在通道上发送消息的 Worker 对象的 createMessageChannel()
方法(将接收 Worker 对象作为参数传递)。
通过 MessageChannel 对象发送消息的典型工作流程如下所述:
-
调用发送 worker 的
createMessageChannel()
方法来创建消息通道// In the sending worker swf var sendChannel:MessageChannel; sendChannel = Worker.current.createMessageChannel(receivingWorker);
-
将消息通道传递到另一 worker:通过调用
Worker.setSharedProperty()
或通过从现有消息通道发送它receivingWorker.setSharedProperty("incomingChannel", sendChannel);
-
接收 worker 中的代码为
channelMessage
事件向 MessageChannel 对象注册一个侦听器// In the receiving worker swf var incomingChannel:MessageChannel; incomingChannel = Worker.current.getSharedProperty("incomingChannel"); incomingChannel.addEventListener(Event.CHANNEL_MESSAGE, handleIncomingMessage);
-
发送 worker 中的代码通过调用
send()
方法发送一条消息// In the sending worker swf sendChannel.send("This is a message");
-
运行时调用接收 worker 代码中的事件处理程序,指出已发送了一条消息
// In the receiving worker swf // This method is called when the message channel gets a message private function handleIncomingMessage(event:Event):void { // Do something with the message, as shown in the next code listing }
-
接收 worker 中的代码调用
receive()
方法来获取消息。receive()
方法返回的对象与传递给send()
方法的对象具有相同的数据类型。var message:String = incomingChannel.receive() as String;
除了上面概述的异步工作流程外,您还可以使用包含 receive()
方法的一个替代工作流程来暂停接收 worker 中的代码并等待至消息被发送。有关更多信息,请参见 receive()
方法说明。
MessageChannel 类是在 worker 之间共享而不是在其之间复制的特殊对象类型之一。当您将消息通道从一个 worker 传递到另一个 worker(通过调用 Worker 对象的 setSharedProperty()
方法或通过使用一个 MessageChannel 对象)时,两个 worker 都引用运行时内存中的同一个 MessageChannel 对象。
相关 API 元素
属性 | 由以下参数定义 | ||
---|---|---|---|
constructor : Object
对类对象或给定对象实例的构造函数的引用。 | Object | ||
messageAvailable : Boolean [只读]
指示在 MessageChannel 的内部消息队列中是否有来自发送 worker 的一条或多条消息。 | MessageChannel | ||
state : String [只读]
指示 MessageChannel 对象的当前状态(open、closing 或 closed)。 | MessageChannel |
方法 | 由以下参数定义 | ||
---|---|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void [覆盖]
使用 EventDispatcher 对象注册事件侦听器对象,以使侦听器能够接收事件通知。 | MessageChannel | ||
指示当前 MessageChannel 在所有消息已接收后关闭。 | MessageChannel | ||
将事件调度到事件流中。 | EventDispatcher | ||
检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器。 | EventDispatcher | ||
表示对象是否已经定义了指定的属性。 | Object | ||
表示 Object 类的实例是否在指定为参数的对象的原型链中。 | Object | ||
表示指定的属性是否存在、是否可枚举。 | Object | ||
从通过此消息通道发送的消息的队列中检索单个消息对象。 | MessageChannel | ||
[覆盖]
从 EventDispatcher 对象中删除侦听器。 | MessageChannel | ||
从发送 worker 发送对象,并将其添加到接收 worker 的消息队列。 | MessageChannel | ||
设置循环操作动态属性的可用性。 | Object | ||
返回此对象的字符串表示形式,其格式设置遵守区域设置特定的约定。 | Object | ||
[覆盖]
返回指定对象的字符串表示形式。 | MessageChannel | ||
返回指定对象的原始值。 | Object | ||
检查是否用此 EventDispatcher 对象或其任何祖代为指定事件类型注册了事件侦听器。 | EventDispatcher |
事件 | 摘要 | 由以下参数定义 | ||
---|---|---|---|---|
[广播事件] Flash Player 或 AIR 应用程序获得操作系统焦点并变为活动状态时将调度此事件。 | EventDispatcher | |||
在发送 worker 每次调用此 MessageChannel 对象的 send() 方法时将调度此事件,指出在 MessageChannel 实例的队列中有一个新的消息对象可用。 | MessageChannel | |||
当消息渠道的 state 属性改变时将调度此事件。 | MessageChannel | |||
[广播事件] Flash Player 或 AIR 应用程序失去操作系统焦点并变为非活动状态时将调度此事件。 | EventDispatcher |
messageAvailable | 属性 |
state | 属性 |
addEventListener | () | 方法 |
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
使用 EventDispatcher 对象注册事件侦听器对象,以使侦听器能够接收事件通知。可以为特定类型的事件、阶段和优先级在显示列表中的所有节点上注册事件侦听器。
成功注册一个事件侦听器后,无法通过额外调用 addEventListener()
来更改其优先级。要更改侦听器的优先级,必须首先调用 removeListener()
。然后,可以使用新的优先级再次注册该侦听器。
请记住,注册该侦听器后,如果继续调用具有不同 type
或 useCapture
值的 addEventListener()
,则会创建单独的侦听器注册。例如,如果首先注册 useCapture
设置为 true
的侦听器,则该侦听器只在捕获阶段进行侦听。如果使用同一个侦听器对象再次调用 addEventListener()
,并将 useCapture
设置为 false
,那么便会拥有两个单独的侦听器:一个在捕获阶段进行侦听,另一个在目标和冒泡阶段进行侦听。
不能只为目标阶段或冒泡阶段注册事件侦听器。这些阶段在注册期间是成对出现的,因为冒泡阶段只适用于目标节点的祖代。
如果不再需要某个事件侦听器,可调用 removeEventListener()
删除它,否则会产生内存问题。事件侦听器不会自动从内存中删除,因为只要调度对象存在,垃圾回收器就不会删除侦听器(除非 useWeakReference
参数设置为 true
)。
复制 EventDispatcher 实例时并不复制其中附加的事件侦听器。(如果新近创建的节点需要一个事件侦听器,必须在创建该节点后附加该侦听器。)但是,如果移动 EventDispatcher 实例,则其中附加的事件侦听器也会随之移动。
如果在正在处理事件的节点上注册事件侦听器,则不会在当前阶段触发事件侦听器,但会在事件流的稍后阶段触发,如冒泡阶段。
如果从正在处理事件的节点中删除事件侦听器,则该事件侦听器仍由当前操作触发。删除事件侦听器后,决不会再次调用该事件侦听器(除非再次注册以备将来处理)。
参数
type:String — 事件的类型。
| |
listener:Function — 处理事件的侦听器函数。此函数必须接受 Event 对象作为其唯一的参数,并且不能返回任何结果,如下面的示例所示:
function(evt:Event):void 函数可以有任何名称。 | |
useCapture:Boolean (default = false ) —
确定侦听器是运行于捕获阶段还是运行于目标和冒泡阶段。如果将 useCapture 设置为 true ,则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。如果 useCapture 为 false ,则侦听器只在目标或冒泡阶段处理事件。要在所有三个阶段都侦听事件,请调用 addEventListener 两次:一次将 useCapture 设置为 true ,一次将 useCapture 设置为 false 。
| |
priority:int (default = 0 ) — 事件侦听器的优先级。优先级由一个带符号的 32 位整数指定。数字越大,优先级越高。优先级为 n 的所有侦听器会在优先级为 n -1 的侦听器之前得到处理。如果两个或更多个侦听器共享相同的优先级,则按照它们的添加顺序进行处理。默认优先级为 0。
| |
useWeakReference:Boolean (default = false ) — 确定对侦听器的引用是强引用,还是弱引用。强引用(默认值)可防止您的侦听器被当作垃圾回收。弱引用则没有此作用。 类级别成员函数不属于垃圾回收的对象,因此可以对类级别成员函数将 |
close | () | 方法 |
public function close():void
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
指示当前 MessageChannel 在所有消息已接收后关闭。
一旦您调用了此方法,您将无法再调用 send()
方法来向队列添加消息。send()
调用将失败并返回 false
。
您也可以只调用 receive()
方法来接收已在队列中等待的消息。如果队列为空,则 receive()
调用将返回 null
。
事件
channelState: — 当调用 close() 方法(此方法将 state 属性设置为 MessageChannelState.CLOSING )时将调度此事件。当已接收了所有消息并且 state 属性被设置为 MessageChannelState.CLOSED 时会再次调度此事件。
|
receive | () | 方法 |
public function receive(blockUntilReceived:Boolean = false):*
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
从通过此消息通道发送的消息的队列中检索单个消息对象。
发送 worker 的代码每次调用 MessageChannel 对象的 send()
方法时,都将向消息通道的内容消息队列中添加一个对象。这些对象将堆积在队列中,直到它们被调用 receive()
方法的接收 worker 一次一个地移除。消息对象的接收将按照发送它们的顺序进行。
要检查队列中是否包含要接收的消息对象,请使用 messageAvailable
属性。
在标准情况下,传递到 send()
的对象将以 AMF3 格式进行序列化。当它被 receive()
调用从队列中移除时,它将反序列化为接收 worker 中的一个 ActionScript 对象(原始对象的一个副本),并且该 worker 将收到对该副本的引用。某些类型的对象是在 worker 之间共享的,而不是在其之间进行复制。在这种情况下,接收 worker 得到的是对共享对象本身的引用而不是该对象的新副本。有关此情况的更多信息,请参见 send()
方法说明。
如果消息队列为空并且您针对 blockUntilReceived
参数传递了 true
,则方法的行为可能会改变。在这种情况下,worker 将在 receive()
调用处暂停其执行线程并且不执行更多代码。一旦发送 worker 调用 send()
,receive()
调用将立即通过接收消息来完成。然后,worker 将从跟在接收调用后的下一行代码继续代码执行。
参数
blockUntilReceived:Boolean (default = false ) — 指示当队列为空时,worker 的执行线程应当接收消息对象然后继续执行 (false ),还是应当在 receive() 调用处暂停并等待消息发送 (true )。
|
* — 发送 worker 传递到 send() 方法的对象的副本。如果该对象是在 worker 之间共享的特殊类型之一,则返回值是对该共享对象的引用而不是对该对象的副本的引用。如果队列上没有消息可用,则此方法将返回 null 。
|
引发
IOError — 如果在调用此方法时通道处于关闭状态,或者如果 blockUntilReceived 参数导致执行暂停并且通道随后被另一 worker 关闭。
| |
ArgumentError — 如果调用代码不在接收 worker 中
| |
ScriptTimeoutError — 如果方法是从 Flash Player 中的原始 worker 中的代码调用的并且 blockUntilReceived 参数导致 worker 暂停的时间超过了脚本超时限制(缺省值为 15 秒)
|
相关 API 元素
removeEventListener | () | 方法 |
override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
从 EventDispatcher 对象中删除侦听器。如果没有向 EventDispatcher 对象注册任何匹配的侦听器,则对此方法的调用没有任何效果。
参数
type:String — 事件的类型。
| |
listener:Function — 要删除的侦听器对象。
| |
useCapture:Boolean (default = false ) —
指出是为捕获阶段还是为目标和冒泡阶段注册了侦听器。如果为捕获阶段以及目标和冒泡阶段注册了侦听器,则需要对 removeEventListener() 进行两次调用才能将这两个侦听器删除,一次调用将 useCapture() 设置为 true ,另一次调用将 useCapture() 设置为 false 。
|
send | () | 方法 |
public function send(arg:*, queueLimit:int = -1):void
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
从发送 worker 发送对象,并将其添加到接收 worker 的消息队列。
传递到 arg
参数的对象几乎可以是任何对象。除了下面指出的例外,传递到 arg
参数的任何对象都不是按引用传递的。在调用 send()
后对一个 worker 中的对象所做的更改不会保留到另一个 worker。对象是通过序列化为 AMF3 格式并在调用了 receive()
时将其反序列化为接收 worker 中的一个新对象进行复制的。因此,无法以 AMF3 格式进行序列化的任何对象(包括显示对象)都不能传递给 arg
参数。为了使自定义类能够被正确传递,必须使用 flash.net.registerClassAlias()
函数或 [RemoteClass]
元数据来注册类定义。无论使用哪种方法,都必须为类的两个 worker 版本使用相同的别名。
有五种对象例外,对它们不适用对象不在 worker 之间共享的规则:
- Worker
- MessageChannel
- 可共享 ByteArray(其
shareable
属性设为true
的 ByteArray 对象) - Mutex
- Condition
如果您将这些对象的一个实例传递给 arg
参数,则每个 worker 都将引用同一个底层对象。在一个 worker 中对实例所做的更改可立即用于另一 worker 中。此外,如果您多次使用 send()
传递了这些对象的同一实例,则运行时不会在接收 worker 中创建对象的新副本。相反,它将重用同一引用,这降低了对系统内存的使用。
默认情况下,此方法将对象添加到队列并立即返回,继续执行下一行代码。如果您希望阻止队列增长到特定大小以上,则可以使用 queueLimit
参数指定队列中可允许的最大项数。如果在您调用 send()
时队列中的项数多于您指定的限制,则 worker 将在 send()
调用处暂停执行线程。一旦 worker 调用 receive()
达到了足够的次数,使得队列大小小于指定的队列限制,则 send() 调用将立即完成。然后,worker 将从下一行代码继续执行。
参数
arg:* — 要添加到消息队列的对象
| |
queueLimit:int (default = -1 ) — 消息队列可以包含的最大消息对象数。如果队列包含的对象超出了此限制,则发送 worker 将暂停执行,直到消息被接收并且队列大小降到此限制之下。
|
事件
channelMessage: — 调度此事件是为了通知接收 worker 在队列中有一个消息对象可用
|
引发
IOError — 如果在调用此方法时通道处于关闭状态,或者如果 queueLimit 参数导致执行暂停并且通道随后被另一 worker 关闭。
| |
ArgumentError — 如果调用代码不在发送 worker 中
| |
ScriptTimeoutError — 如果方法是从 Flash Player 中的原始 worker 中的代码调用的并且 queueLimit 参数导致 worker 暂停的时间超过了脚本超时限制(缺省值为 15 秒)
|
相关 API 元素
toString | () | 方法 |
channelMessage | 事件 |
flash.events.Event
属性 Event.type =
flash.events.Event.CHANNEL_MESSAGE
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
在发送 worker 每次调用此 MessageChannel 对象的 send()
方法时将调度此事件,指出在 MessageChannel 实例的队列中有一个新的消息对象可用。
Event.CHANNEL_MESSAGE
常量定义 channelMessage
事件对象的 type
属性的值。
此事件具有以下属性:
属性 | 值 |
---|---|
bubbles | false |
cancelable | false ;没有要取消的默认行为。 |
currentTarget | 当前正在使用某个事件侦听器处理 Event 对象的对象。 |
target | 调度此事件的对象。 |
channelState | 事件 |
flash.events.Event
属性 Event.type =
flash.events.Event.CHANNEL_STATE
语言版本: | ActionScript 3.0 |
运行时版本: | Flash Player 11.4, AIR 3.4 |
当消息渠道的 state
属性改变时将调度此事件。
Event.CHANNEL_STATE
常量定义 channelState
事件对象的 type
属性的值。
此事件具有以下属性:
属性 | 值 |
---|---|
bubbles | false |
cancelable | false ;没有要取消的默认行为。 |
currentTarget | 当前正在使用某个事件侦听器处理 Event 对象的对象。 |
target | 调度此事件的对象。 |
Tue Jun 12 2018, 11:04 AM Z