2014-06-09 92 views
0

我是新來的動作,我正在按照約瑟夫德沃爾的教程。我明白,當我想要做一個網絡查詢時,我可以創建一個URLRequest,並用URLLoader發送。我期望在URLLoader.data屬性中找到響應數據,但是在完成查詢之後,在我的情況下這仍然爲空。然後,我似乎必須創建一個事件處理來實際訪問響應。這是真的?我真的需要爲URLLoader提供一個事件處理程序嗎?

我寫了這個小示例代碼,並想知道我(最簡單的方法)如何訪問此獲取請求中的響應。

package 
{ 
    import flash.events.Event; 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 

    public class stackQuery 
    { 
     public function stackQuery() 
     { 
     } 

     public function makeQuery(): String { 
      var request: URLRequest = URLRequest("http://www.google.com"); 
      var loader: URLLoader = new URLLoader(); 
      loader.addEventListener(Event.COMPLETE, handleResponse); 
      try{ 
       loader.load(request); 
      } 
      if(loader.data == null){ 
       return "Empty" 
      } 
      return "data not empty" 
      } 

      private function handleResponse(event:Event):void 
      { 
       //something with event.target.data here?? 
      } 
    } 
} 
+0

我不認爲有什麼好辦法做一個同步負載(就像你可以在一些其他語言)。 – BadFeelingAboutThis

回答

1

使用AS3沒有任何好的方法可以執行同步加載(就像其他語言一樣)。您的數據爲空,因爲在AS3中,加載命令是異步的 - 意味着它不會暫停應用程序的其餘部分(將其鎖定),直到加載完成,它會移至下一行代碼,並在加載後調度事件做完了。

這裏,你會如何想這個基於關閉您提供的代碼來處理代碼示例:

package 
{ 
    import flash.events.Event; 
    import flash.events.IOErrorEvent; 
    import flash.events.SecurityErrorEvent; 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 

    public class stackQuery 
    { 
     private var loader: URLLoader = new URLLoader(); //let's move it out to the class level so you can easily reference it from other methods (though this is purely optional) 

     public function stackQuery() 
     { 
     } 

     public function makeQuery(): String { 
      var request:URLRequest = URLRequest("http://www.google.com"); 


      //add you listeners before loading 
      loader.addEventListener(Event.COMPLETE, handleResponse); 
      loader.addEventListener(IOErrorEvent.IO_ERROR, handleResponse); //it's good practice to also listen for errors 
      loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleResponse); //this kind of error will happen if you're trying to load a local resource but have published as network only (or vice-versa) 

      //load the request, any code after this will run before the load completes. 
      loader.load(request); 
     } 

      //this function will run once the load completes 
     private function handleResponse(event:Event):void 
     { 
      if (event is IOErrorEvent) { 
       //you had an IO error, better do something 
       return; 
      } 

      if (event is SecurityErrorEvent) { 
       //url wasn't allowed to load 
       return; 
      } 

      trace(loader.data); //this is what was returned from the page 
       //you could also get it by referencing the currentTarget of the event 
       trace(URLLoader(event.currentTarget).data); 
     } 
    } 
} 
1

是的,當然是的。想象一下你加載了一兆字節的數據。你需要時間來加載它,對吧?因此,您無法在下一行代碼中獲得這些數據。

偵聽器將在目標調度事件時得到執行 - 在您的情況下,當該兆字節被加載時。

這是一個正常的行爲。

+0

那麼我應該在handleResponse()中添加什麼,以便makeQuery()將返回字符串「data not empty」? – stian

+0

@安德瑞所說的是,你不能指望從'makeQuery'返回任何有意義的東西。 – Marcela

+0

@marcela。這意味着makeQuery實際上有時間在handleResponse被調用之前完成? – stian

1

雖然給出的答案是正確的,真正的解釋是,ActionScript 3的是一個異步的語言而不是像Python這樣的其他語言,它們是同步的。在python加載類似url之後,下一行代碼將不會被執行,直到url被加載(這可以創建滯後或空閒執行),在ActionScript 3中,代碼執行不會等待並移動到下一行。這就是您需要使用事件的原因(Actionscript 3是一種基於事件的語言),因此您可以瞭解當您的代碼仍在執行時,您所等待的數據何時可用。

+0

動作腳本**是具有異步功能的同步語言,如Event系統。這個特定的問題是使用異步調用的很好的例子。但是如果你不處理事件,大多數事情都是同步的。 –

相關問題