2017-08-25 87 views
0

我在Adobe的Flex 4(ActionScript 3的)的函數,它接受一個對象,並返回一個ArrayCollection ...在ActionScript創建延遲3個功能

如果某個全局變量設置爲true,我想要的功能在運行之前延遲3秒。否則,我希望該功能正常運行。

的問題是,如果我用一個定時器,該定時器調用單獨功能,以及任何函數不能返回我的調用函數,也不能調用函數接受任何參數,所以它不喜歡我可以在TimerComplete事件觸發後遞歸地調用我自己的函數...並且遞歸調用將不起作用,因爲它會將ArrayCollection返回到定時器結果函數,而不是返回原始調用函數...

I需要延遲以內的這個函數,而不是延遲,導致我超出這個函數。但我無法弄清楚如何去做。

像這樣的東西是什麼,我需要做的:

private function createArrayCollection(myObject:Object):ArrayCollection { 

    var myArrayCollection:ArrayCollection = new ArrayCollection(); 

    if (globalWaitBoolean) { 
     //delay here for 3 seconds, somehow 
    } 

    //Here I do the stuff that uses the info in myObject to figure out what to 
    //put into the ArrayCollection I want to return 

    return (myArrayCollection); 
} 

所以......關於如何做到這一點,而無需調用外部定時器功能無法返回一個對象回到我原來的功能,任何想法?

感謝,

回答

2

你想要的方式,你將有你的整個應用程序滯後3秒,反應遲鈍到任何用戶輸入和外部事件。但它是可能的,肯定的:

import flash.utils.getTimer; 

private function createArrayCollection(myObject:Object):ArrayCollection 
{ 
    var myArrayCollection:ArrayCollection = new ArrayCollection; 

    if (globalWaitBoolean) 
    { 
     var waitUntil:int = getTimer() + 3000; 

     // Method getTimer() returns time in ms passed since app start. 
     // So you just have to wait until it is greater than appointed time. 
     while (getTimer() < waitUntil) 
     { 
      // Do nothing. 
     } 
    } 

    return (myArrayCollection); 
} 

不過,如果你想這樣做,在做這件事的正確方式:

import flash.utils.setTimeout; 

private function callerMethod():void 
{ 
    // Blah blah blah. 
    // ... 
    // Finally. 
    createArrayCollection(sourceData, asyncResult); 
} 

private function createArrayCollection(myObject:Object, handler:Function):void 
{ 
    var result:ArrayCollection = new ArrayCollection; 

    if (globalWaitBoolean) setTimeout(handler, 3000, result); 
    else handler(result); 
} 

private function asyncResult(source:ArrayCollection):void 
{ 
    // The rest of your processing code. 
} 
+0

是的,不幸的是,無法完成正確的方式,因爲調用者程序是一個Adobe AIR程序,如果不在數百臺客戶機上更新它,我無法更改它 - 程序調用的函數在「模塊「只有一個客戶端遇到問題,因此爲一個客戶端修改模塊要比爲數百個客戶端修改AIR應用程序要容易得多。因此,我需要這種荒謬的,不正確的編程實踐,使它只爲這個客戶工作。非常感謝您的答覆 - 這正是我所期待的。 –

+0

哦 - 僅供參考,如果我在while循環中添加一行說this.ValidateNow(),我認爲它可能實際上允許與程序交互,而它正在等待定時器通過。至少,我會嘗試一下,看看會發生什麼。即使它將程序鎖定3秒鐘,也只有一個客戶端會遇到這個問題,而且每隔一段時間就會遇到一次。 –

+0

@LaurenceMacNeill不,它不會。 Flash應用程序對AS3腳本有一個執行線程,所以在遍歷這個空循環時它不會做任何事情。 – Organis

1

普通(同步)碼流不會返回,直到值已準備好,所以如果您希望實際等待3秒鐘,而不允許應用程序執行任何操作,請使用@ Organis的答案的getTimer()方法。如果你想要獲得異步結果,你需要面對並克服更多的問題。

首先,您預計何時會返回ArrayCollection實際到達。談到代碼設計,異步代碼需要大量的假設,線程安全等等,即使AS3/Flash沒有真正的多線程,除非您計數爲Worker s,但帶有事件的代碼流並不那麼明顯。所以,不管誰打電話給你的人,都不應該期望從它返回的價值馬上。所以,談到你的直接問題,不,如果你需要一個響應式應用程序,你不能避免某種定時器。但是你可以通過一種涉及間接返回結果的方法來使用它們。

其次,如果您的應用程序需要這些對象,是否可能會有來自對象的更多數組集合的同時請求 - 您必須爲可能由此造成的任何干擾做準備。假設你的功能是通過點擊按鈕觸發的 - 如果該按鈕在3秒內被點擊多次,該怎麼辦?

第三,處理代碼的實際路由不是直接與異步返回。您需要一個回調函數,一個事件處理函數(本質上是一個半原生的回調函數),一個定期檢查值存在的代碼(輸入幀處理函數等)或類似的技巧來收集異步返回的值,然後傳遞它涉及任何相關的代碼,將進一步處理它。因此,您需要設計一個能夠接收復雜數據的接口(源對象向前,數組收集向後),然後針對所有可能的情況和缺陷仔細測試它。

一個實現所有這些很長的例子,我會盡力以某種方式概述它。 Ler假設你有一種「服務器」類,它接受數據請求並同步處理(不等待)或異步處理(等待)。它接受類型爲「T」的源對象,並提供一個類型爲ArrayCollection的新創建對象,該對象作爲參數提供給發送給它的任何回調函數。它也接受延遲(一種簡單的方式來顯示同步/異步返回將是一個布爾值,但爲什麼不獲得一個int?)作爲參數,並保證(在事件模型限制的範圍內),在這個延遲之後,回調將被稱爲儘快。架構將如下所示:

class Processor { 
    Dictionary requests; // here all the requests that are delayed will be stored 
    public function dpr(source:T,callback:Function,delay:int=0):void{...} 
    // creates requests and stores them 
    private function syncProcess(source:T):ArrayCollection {...} 
    // whatever routine you want to get variably delayed 
    private function processTimeout(e:Event=null):void {...} 
    // processes events from "setTimeout()" and calls callbacks 
} 

請注意,異步方法被迫創建三個實體,而不是同步實例。首先是請求保持結構(字典在這裏),第二是超時事件處理程序,第三是你希望在數據準備好時調用的回調。碼流會是這樣的:

同步調用,會導致從類中直接調用回調:request - >processTimeout - >syncProcess() - >callback。異步呼叫將在Timer::timerComplete事件處理程序中通過調用request中的setTimeout調用回調,最初來自request的數據存儲在requests中。

+0

這是一個調用該函數的Adobe AIR應用程序,該應用程序包含在AIR應用程序加載的Flex「模塊」中。 AIR應用程序*應該等待,直到它在執行其他任何操作之前獲取ArrayCollection。該模塊創建打印作業,其中一個打印作業*可能是信封,比普通打印作業花費的時間更長。如果我不停止這個過程並等待信封打印,Windows會很樂意將這份打印作業存儲很長時間,並在多個作業結束後將其打印出來 - 從而使所有內容都不可用-訂購。我不知道爲什麼。 –

+0

而且,是的,停止一切等待一個愚蠢的信封打印是一個徹頭徹尾的黑客工作。但在這一點上,我已經耗盡了所有我能想到的東西。這是一個Windows問題,不幸的是,我的Flex「模塊」內部幾乎沒有任何Windows控制。 –

+0

Hm-m-m。使用AS3打印是我從未真正做過的事情,是的,可能存在問題。不過,我想知道,如果您真的可以在AS3應用程序中拆分作業,以便正常工作首先進行,那麼如果存在該信封,則會延遲該信封,並顯示一個彈出窗口,如「準備就緒時單擊」,然後將該信封發送給打印機? – Vesper

1

你可以使用嵌入式/內聯函數:

private function createArrayCollection(myObject:Object):ArrayCollection { 

    var myArrayCollection:ArrayCollection = new ArrayCollection(); 

    if (globalWaitBoolean) { 
     var milliseconds:int = 3000; 
     //delay here for 3 seconds 
     setTimeout(function() 
     { 
      //Here I do the stuff that uses the info in myObject to figure out what to 
      //put into the ArrayCollection I want to return 
      return (myArrayCollection); 
     }, 
     milliseconds); 
    } 
    else 
    { 
     //Here I do the stuff that uses the info in myObject to figure out what to 
     //put into the ArrayCollection I want to return 
     return (myArrayCollection); 
    } 
} 

的內部函數可以訪問外部函數的所有本地變量。