套件 | 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.setSharedProperty()
,或者透過現有訊息通道來傳送的方式,將訊息通道傳遞至其他 WorkerreceivingWorker.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 物件的 setSharedProperty()
方法或使用 MessageChannel 物件,將訊息通道從一個 Worker 傳遞到另一個 Worker 時,兩個 Worker 都會參考執行階段記憶體中相同的 MessageChannel 物件。
相關 API 元素
屬性 | 定義自 | ||
---|---|---|---|
constructor : Object
類別物件的參照或是特定物件實體的建構函數。 | Object | ||
messageAvailable : Boolean [唯讀]
指出 MessageChannel 的內部訊息佇列中有來自傳送端 Worker 的一個或多個訊息。 | MessageChannel | ||
state : String [唯讀]
指出 MessageChannel 物件的目前狀態 (開啟、關閉中或已關閉)。 | 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()
。 然後,您就可以使用新的優先順序等級來重新註冊偵聽程式。
請記住,一旦您註冊了偵聽程式,對 addEventListener()
進行後續呼叫,若使用不同的 type
或 useCapture
值,將會導致建立個別的偵聽程式註冊程序。 例如,如果您先將 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()
方法時,就會在訊息通道的內部訊息佇列中加入一個物件。這些物件會堆在佇列中,直到接收端 Worker 呼叫 receive()
方法逐一移除為止。訊息物件會依傳送的順序進行接收。
若要檢查佇列是否包含要接收的訊息物件,請使用 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。當呼叫 receive()
時,物件會透過序列化為 AMF3 格式並還原序列化為接收端 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, 03:47 PM Z