1

我正在使用 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为空。

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

4

2 回答 2

2

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

如果你这样做,每个响应者都会根据需要触发它的结果或错误处理程序。然后使用 Sam DeHaan 建议的最后一种方法,在调用时将每个令牌存储在一个数组中,并在执行“结果”或“故障”处理程序时从数组中删除该令牌。从数组中删除令牌时,如果数组为空,您可以重新启用按钮。

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

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);
于 2012-04-11T23:21:44.263 回答
0

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

于 2012-04-11T17:42:16.103 回答