2009-12-31 116 views
1

比方說,我有一些像這樣的代碼在AS3我可以強制執行腳本動作代碼嗎?

for(...) 
    thing = new Thing(...) 

對事物的構造將會導致被渲染到一些影片剪輯的SWF。 如果循環運行10次左右,大多數時候我只會得到在剪輯上顯示的東西的子集。我猜這是閃存在同一時間加載一堆東西的問題。

我已經能夠通過將回調傳遞給Thing構造函數來解決此問題,並且只有在先前的Thing完全加載並回調後才繼續循環。

首先,這是一個已知的問題嗎?或者我以錯誤的方式解決這個問題? 其次,有沒有什麼辦法可以告訴flash /以線性方式運行此代碼而不用回調?在任何地方都會遇到這種煩人的事情。


編輯:

所以我覺得richardolsson是正確的,我們必須做一些錯誤的。爲了重申這個問題,如果我嘗試將多個swfs加載到舞臺上,即使只有兩到三個,但不等待前一個完成加載,我將加載一個不可預知的數字。例如,運行循環10次以上,我可能會得到加載的第二,第五和第十物。其他人似乎以異步方式迷路。 Flash在這些情況下顯示沒有運行時錯誤。所以這裏是我們如何做事的基本想法。

我們有一個基類,我們擴展了大多數加載swfs的類。它看起來像這樣:

public function base(path:string, parent:sprite, callback:function) 
{ 
    //this is the child swf path 
    _path = path; 

    //parent is the sprtie we want to render the child onto 
    if(parent != null) doLoad(parent, callback) 
} 

public function doLoad(parent, callback) 
{ 
    var mLoader:Loader = new Loader(); 
var mRequest:URLRequest = new URLRequest(_path); 

    //onLoaded is overridden in the child. The override first calls the parent onLoad. 
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded); 

    mLoader.load(mRequest); 
} 

//this is called from the load complete from above. This is done before the 
//child onloaded is done 
protected function onLoaded(loadEvent:Event):void 
{ 
    _loadedTarget = loadEvent.currentTarget; 
    _canvas = _loadedTarget.content; 
    _parentSprite.addChild(_canvas); 
} 

現在,我們大多數需要顯示Swf的類都擴展了這個類。他們看起來像這樣

public class child extends base 
{  

public function child(parent:Sprite, callback) 
{ 
    //call base constructor 
    super("some/path/to/swf", parent, callback); 
} 

protected override function onLoaded(loadEvent:Event):void 
{ 

    super.onLoaded(loadEvent); 
    .... 
} 

這是基本的方案。如果我嘗試創建一堆'child'的實例,而不等待onLoaded函數完成之前的'child',則隨機實例將不會顯示。我很快就寫了上面的代碼,它不是compy/paste,所以忽略簡單的錯誤。上述方法不起作用有什麼明顯的原因嗎?

+0

您在使用播放器的調試器版本和你肯定沒有運行時錯誤拋出?你試圖達到的目標不應該成爲一個問題。 – 2010-01-04 15:25:19

回答

2

難道是因爲你在聲明局部範圍的SWF加載程序?它很有可能會掉到範圍之外,並在它有機會加載前被垃圾收集。

+0

這可能是答案。這似乎是有道理的,但因爲這是半隨機發生的,所以我無法確定。如果一切都好幾天,我會考慮這個答案。 – Erix 2010-01-06 14:25:32

1

這不是一個問題,因爲它是一種不同的思維方式。而不是以一種必要的,程序化的方式來思考你的程序(即做到這一點,做到這一點,做另一種做法),把你的程序看作面向對象的事件事件。 (即X的完成觸發事件,Y是注意事件的事情)。我仍然不時與我的大腦戰鬥。

也許事件監聽器更符合您的需求?對象可能會在完成時觸發某些事件,並且其他代碼可能會偵聽這些事件。

+0

我明白你在說什麼,很難從更多的c背景中獲得。如果它按照我認爲應該的方式工作(實際上加載所有10件事),它不會是這樣的問題 – Erix 2009-12-31 15:21:07

1

我覺得你的Thing實例沒有出現,這聽起來很奇怪。儘管在編寫Flash時經常需要採用異步思維的方式,但是您描述這種特殊情況的方式會讓我覺得您做錯了什麼。加載一堆SWF文件並將它們放置在舞臺上時,Flash應該沒有問題,特別是不要少於十次。

只要您使用單獨的Loader實例,並將這些加載器中的每一個添加到舞臺(或者在Event.COMPLETE事件觸發後添加它們的內容),理論上應該可以加載無限數量的SWF文件。瀏覽器可能會對可能存在的連接數量進行一些限制,所以會對它們排隊,但這對Flash Player是透明的,對於代碼更是如此。

如果您使用更實際的代碼示例編輯帖子,可能會更容易發現問題。

乾杯

+0

我認爲你是對的,我們做錯了什麼。請參閱編輯。 – Erix 2010-01-04 15:01:32

0

我不認爲你已經提供了足夠的信息來得到明確的答案。

這聽起來像你的「物」的對象具有某種初始化它是異步的,因此執行路徑是不可預測的,因爲一個給定的請求可以完成出故障了。

您可能無法從字面上管理的執行路徑,而是讓他們至少在用戶看來,就好像它們按順序執行,你可以採取措施來管理的對象。

即分配一個索引給定對象或參考回包含一系列的對象陣列,和具有他們分析彼此以查看哪些已經完成,然後相應地運行。

歸根結底這是非常愚蠢的,你應該考慮的應用設計中不能同時在異步事件和線性執行的外觀生存。

但確實,要給出明確的答案,您需要告訴我們更多關於您的問題的信息。如果從正確的角度來看,通常有一個簡單的解決方案。

0

不聽起來應該是一個問題,但另一方面,我從來沒有觸發過10次調用來同時加載sw。

總的來說,我使用某種類型的負載隊列,在對象被添加(任選的優先級,讓他們的重要性順序排序),當在隊列前面的項目已完成加載被加載。

一些一般性的有用的提示:

  1. 使用webproxy監測究竟是什麼回事您的Flash應用程序和服務器之間。我真的很高興與查爾斯(http://www.charlesproxy.com/)。它具有一些額外的非常有用的功能,如節流(僞裝慢速D/L速度)等。
  2. 使用跟蹤來監控代碼的「流程」究竟發生了什麼。很多時候,你認爲你的代碼達到了某個特定的點,而實際上它並沒有。將痕跡放在代碼中的關鍵點上。顯然,使用調試器會更好。一個非常通用的(並且非常容易學習如何使用)調試器是MonsterDebugger(http://demonsterdebugger.com/)實際上它是一個記錄器,但它無論如何會對你有很大的幫助。
+0

查爾斯+1。這完全值得50美元,我每天都在工作中使用它。 – richardolsson 2010-01-05 18:50:29

1

我要去刺這個。儘管我的AS技能有點生疏。

您的...

protected function onLoaded(loadEvent:Event):void 
{ 
    _loadedTarget = loadEvent.currentTarget; 
    _canvas = _loadedTarget.content; 
    _parentSprite.addChild(_canvas); 
} 

你能......嗎?

var _loadedTarget = loadEvent.currentTarget; 
var _canvas = _loadedTarget.content; 

要保留這些在所謂onLoaded我想沒有變種的範圍,它可能會附加這些變量的外部範圍和每個裝載的被調用時覆蓋它們。

或......?

_parentSprite.addChild(loadEvent.currentTarget._canvas); 

因此,您不必設置任何變量並完全消除任何可能的範圍問題。

或者......也許......?

_loadedTarget[] = loadEvent.currentTarget; 
_canvas[] = _loadedTarget[_loadedTarget.length-1].content; 
_parentSprite.addChild(_canvas[_canvas[_canvas.length-1]); 

您怎麼看?

1

有一種非常簡單的方法來對異步下載進行排序。只要給Loader一個名字! :)

  var pic2loadcount:int = ProjectspictureNames.length; 
     var ImageLoader:Loader; 
     for (var counter:int = 0; counter < pic2loadcount; counter++) { 
      ImageLoader = new Loader(); 
      ImageLoader.name = String(counter);    
      ImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE , onProjectImagesLoaded); 
      ImageLoader.load(new URLRequest(path2pics + ProjectspictureNames[counter]));    
     } 

終於在你的onProjectImagesLoaded功能,搶的域名(onProjectImagesLoaded),轉換爲回一個int,並準備好進行排序! :)

乾杯, 德克

相關問題