Solved

Pause script execution inside Actionscript 3 function

Posted on 2008-10-07
5
9,124 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

Question has a verified solution.

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

Suggested Solutions

In my long career of working as an actionscript developer, I had spent sleepless night often working hard to solve some small problems which actually took a lot of my development time; later found out the solutions to be a line or two. Here are s…
While working over numerous projects I often had the requirement for doing a screen capture in AS3.0. Unfortunately I found no "ready made" solutions in google search that suited my requirements. But I did come across some great resources which help…
The goal of the tutorial is to teach the user how to live broadcast using Flash Media Live Encoder and connecting it to YouTube to broadcast. Log into your Youtube account, choose live stream settings, start live stream from Flash Media Live Enc…
The goal of the tutorial is to teach the user how to select the video input device. Make sure you have an input device that in connected and work and recognized by Adobe Flash Media Live Encoder and select it in the “video input” menu.

739 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