Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 9317
  • Last Modified:

Pause script execution inside Actionscript 3 function

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
Soluch
Asked:
Soluch
  • 3
  • 2
1 Solution
 
BarjawiCommented:
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
 
BarjawiCommented:
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
 
SoluchAuthor Commented:
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
 
BarjawiCommented:
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
 
SoluchAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now