I’m using Flash Builder 4.6. As a simple example, say I have the following application:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:sdk="services.sdk.*">
<fx:Script>
<![CDATA[
private function btnGetValue_clickHandler():void
{
getValueResult.token = sdk.getValue();
}
private function getValueResultHandler():void
{
// ...
}
]]>
</fx:Script>
<fx:Declarations>
<sdk:SDK id="sdk" fault="{Alert.show(event.fault.faultString +'\n\n'+ event.fault.faultDetail, 'SDK ERROR');}" showBusyCursor="false"/>
<s:CallResponder id="getValueResult" result="getValueResultHandler()"/>
</fx:Declarations>
<s:Button id="btnGetValue" click="btnGetValue_clickHandler()" label="Get Value" />
</s:Application>
So when you click on the button, it calls a PHP file and when it gets a result, it calls getValueResultHandler(). Easy enough.
But what if the response from the PHP file takes a second or two and the user clicks the button rapidly? Then the result handler function may not get called every time, since the call responder gets a new token before it received the last response.
Is there a standard way of resolving this issue? I came up with the following workaround, and it works fine, but it seems like this issue would be common enough to have a more built-in solution.
My workaround is:
var getValueResultProcessing:Boolean = false;
private function btnGetValue_clickHandler():void
{
var interval:uint = setInterval(function():void
{
if (!getValueResultProcessing)
{
getValueResultProcessing = true;
getValueResult.token = sdk.getValue();
clearInterval(interval);
}
}, 100);
getValueResult.token = sdk.getValue();
}
private function getValueResultHandler():void
{
getValueResultProcessing = false;
// ...
}
Any better way of resolving this issue?
EDIT:
One of my actual scenarios for which I need a solution is when looping:
private function btnGetValue_clickHandler():void
{
var arr:Array = new Array("value1", "value2", "value3");
for each (var value:String in arr)
getValueResult.token = sdk.getValue(value);
}
So to solve this problem I make arr a global variable and use the setInterval method I described before to shift off the first element and then do the same exact thing in the result function until arr is empty.
Again, looking for a more “standard” solution, if such a thing exists.
Instead of using
CallResponder, you might want to manage the responses to service calls yourself. HTTPService (or similar Flex services) return anAsyncTokenwhen you call theHTTPService.send()method. You can then add ‘result’ and ‘fault’ handlers by using theAsyncToken.addResponder()method.If you do it this way, each responder will trigger it’s result or fault handler as appropriate. Then use the last approach as suggest by Sam DeHaan, where you store each token in an array when the call is made, and remove the token from the array when the ‘result’ or ‘fault’ handler is executed. When removing a token from the array, you can re-enable the button if the array is empty.
You do it something like this (typing code from memory):