检查CallResponder是否正在处理

时间:2012-04-11 17:26:38

标签: flex asynchronous

我正在使用Flash Builder 4.6。举个简单的例子,假设我有以下应用程序:

<?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>

因此,当您单击该按钮时,它会调用一个PHP文件,当它获得结果时,它会调用getValueResultHandler()。很容易。

但是,如果PHP文件的响应需要一两秒钟,并且用户快速单击该按钮,该怎么办?然后,每次都不会调用结果处理程序函数,因为调用响应程序在收到最后一个响应之前会获得一个新标记。

是否有解决此问题的标准方法?我提出了以下解决方法,它运行正常,但似乎这个问题足够普遍,有一个更内置的解决方案。

我的解决方法是:

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;
    // ...
}

解决此问题的更好方法是什么?

<小时/> 修改

我需要解决方案的一个实际场景是循环时:

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);
}

因此,为了解决这个问题,我将arr作为一个全局变量并使用我之前描述的setInterval方法将shift关闭第一个元素,然后在结果中执行相同的操作函数直到arr为空。

再次,寻找更“标准”的解决方案,如果存在这样的事情。

2 个答案:

答案 0 :(得分:2)

您可能希望自己管理对服务调用的响应,而不是使用CallResponder。调用AsyncToken方法时,HTTPService(或类似的Flex服务)返回HTTPService.send()。然后,您可以使用AsyncToken.addResponder()方法添加“结果”和“错误”处理程序。

如果你这样做,每个响应者将适当地触发它的结果或错误处理程序。然后使用Sam DeHaan建议的最后一种方法,在调用时将每个标记存储在数组中,并在执行'result'或'fault'处理程序时从数组中删除标记。从阵列中删除令牌时,如果阵列为空,则可以重新启用该按钮。

你这样做(从内存中输入代码):

var service:HTTPService = new HTTPService();
// configure the service...
var token:AsyncToken = service.send();
// resultHandlerMethod and faultHandler method are functions that you should define
// their signatures look like this:
// resultHandlerMethod(event:ResultEvent)
// faultHandlerMethod(event:FaultEvent)
token.addResponder(new Responder(resultHandlerMethod, faultHandlerMethod);

答案 1 :(得分:0)

如果呼叫是基于按钮的,请在点击时禁用该按钮。在回调结束时启用按钮。简单。