Solved

Pause script execution inside Actionscript 3 function

Posted on 2008-10-07
5
9,081 Views
Last Modified: 2013-11-11
Looking for a way to pause execution of a function before returning data.

Please see the code in the doRequest function where the "// wait" line is.  I want to pause execution here without making the application hang.  

I've looked at setInterval, but unfortunately that will not do the trick, well not that I can see anyway.

There is a similar solution at the link below, but I am looking for something that uses HTTPService.

http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=2&postId=7184 

Thanks!

private var ready:Boolean = false;
private var data:Object = null;
 
public function doRequest(url:String, data:Object):Object{
    var h:HTTPService = new HTTPService;
    
    h.url = url;
    h.showBusyCursor = true;
    h.useProxy = false;
    h.method = "POST";
    h.addEventListener("result", doRequest_done);
    h.send(data);
    
    // wait for data to be ready
    while (!ready){
        // wait
        
    }
    
    // do return
    return data;			
}
 
private function doRequest_done(e:ResultEvent):void{
    data = e.result;
    ready = true;
}

Open in new window

0
Comment
Question by:Soluch
  • 3
  • 2
5 Comments
 

Accepted Solution

by:
Barjawi earned 250 total points
ID: 22672324
Unfortunately Actionscript 3 is single-threaded. You can't have something work in the background and have the UI do something else.

Similarly, there is no yielding or blocking in Actionscript 3. If the next line of code is supposed to run, you cannot prevent the next line of code from running.

The solution to your problem will be events. When you want to do something at a certain time or after a certain event, you should wait until that time comes and then create and dispatch an event. A callback function gets called in which you do the thing that you intend on doing.

So in your code, you want to wait until the data is ready. You already have an event listener for when the data is ready. When it is, the "doRequest_done" is called. In there you should return the code (by calling a function that resides in the place where you want "data" to go to, for example).

I have another solution for you, since you are using Actionscript 3, if you have your code inside a class, you can put a listener on the class object. When the "doRequest_done" is called, you dispatch the event and the callback method gets called through which you send your data.

import flash.events.Event;
 
// You should create an event class
public class myEvent extends Event {
   // the name of the event
   public static const DATA_READY:String = "dataReady";
 
   // the variable that will store your data object
   private var _data:Object;
 
   public myEvent(type:String) {
      super(type);
   }
 
   public function get data():Object { return _data; }
   public function set data(value:Object):void { _data = value; }
}
 
// ==================
 
import flash.events.EventDispatcher;
 
// now in your class, you do the following
public class XYZ {
   private var data:Object = null;
   private var ed:EventDispatcher;
 
   public function doRequest(url:String, data:Object):Object{
       var h:HTTPService = new HTTPService;
    
       h.url = url;
       h.showBusyCursor = true;
       h.useProxy = false;
       h.method = "POST";
       h.addEventListener("result", doRequest_done);
       h.send(data);
   }
 
   private function doRequest_done(e:ResultEvent):void{
       data = e.result;
       var x:myEvent = new myEvent(myEvent.DATA_DONE);
       x.data = data;
       // it depends on what this class extends, you might not need to create an event dispatcher
       ed = new EventDispatcher();
       ed.dispatchEvent(x);
   }
}
 
// now in the other place where you want to receive the data object
var myObject:XYZ = new XYZ();
myObject.addEventListener(myEvent.DATA_DONE, dataDoneHandler);
 
public function dataDoneHandler(event:myEvent):void {
   trace("data object is: " + event.data);
}

Open in new window

0
 

Expert Comment

by:Barjawi
ID: 22674120
Some notes, if you want to test my code above, make sure:
1- Change the (DATA_READY) in the (myEvent) class into (DATA_DONE).
2- The XYZ class does not have (addEventListener) function. To have that, the XYZ class has to extend another class that had the (addEventListener) function. For example, you can extend (Form) or (Canvas).
0
 
LVL 2

Author Comment

by:Soluch
ID: 22674972
Thanks Barjawi.  

I've already used events and find them a pain when you need to determine what to do next based on the results of the previous call.  What can be done in one function with a few if/else statements ends up being several different functions / handlers.

Thanks for your suggestion anyway, but unfortunately it doesn't solve the issue.

I've gone with a custom synchronous function that does what I need, but I have now encountered a different problem.  Perhaps I should open a new question for it, but I'll explain it here and maybe someone can help.

This could be related to threading, but it seems that code isn't executed in the order it's written.  For example, in the code below, CursorManager.setBusyCursor isn't being executed until the line below it has finished.

The line var data:Object... takes a few seconds to run, so what I want to do is display a busy cursor first, then run the code, but for some reason it's not working as expected. (I've also tried just putting in a plain Alert.show("test"); but that also doesn't show up until the request has come back).

Still learning Flex/ActionScript, so not sure how processing works, but maybe this just could be a limitation of the language.

CursorManager.setBusyCursor();
var data:Object= r.request("user.php", "request=user_list", false).data;
 
acUsers = data.users.user as ArrayCollection;
dgUsers.dataProvider = acUsers;
 
.
.
.
 
// remove busy cursor

Open in new window

0
 

Expert Comment

by:Barjawi
ID: 22675020
It seems that r.request is a blocking function. Because the code executes quickly, when it reaches to your Alert or setBusyCursor statements it starts executing them. While executing them, the function call r.request() executes which blocks the execution of your application until it returns. After which it continues where it left (by showing the Alert or the cursor).
0
 
LVL 2

Author Comment

by:Soluch
ID: 22728045
Thanks for taking the time to reply to the questions.  I'll accept your solution for the effort you put in with the code, etc.  It's just a pity AS3 is single-threaded.

Thanks again.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
Sometimes you know that one object has a specific child in it, but you can't find the child. This happened to me when I was trying to code some actionScript to make a toolbar work with its embedded buttons.  My partner had created the toolbar usi…
The goal of the tutorial is to teach the user how to how to record live broadcast.
The goal of the tutorial is to teach the user how to select which audio input to use. Once you have an audio input plugged into the laptop or computer, you will go into the audio input settings and choose which audio input you want to use.

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question