我在Adobe Flex 4(ActionScript 3)中有一个函数,它接受一个对象并返回一个ArrayCollection ......
如果某个全局变量设置为true,我希望该函数在运行前延迟3秒钟。否则我希望该函数正常运行。
问题是,如果我使用Timer,该计时器调用单独的函数,并且该函数不能向我的调用函数返回任何内容,它调用的函数也不能接受任何参数,所以它& #39;不像我可以在TimerComplete事件触发后递归调用我自己的函数...并且递归调用无论如何都不会工作,因为它会将ArrayCollection返回到timer-result函数,而不是原来的调用函数......
我需要在函数中延迟,而不是导致我超出该函数的延迟。但我无法弄明白该怎么做。
这是我需要做的事情:
private function createArrayCollection(myObject:Object):ArrayCollection {
var myArrayCollection:ArrayCollection = new ArrayCollection();
if (globalWaitBoolean) {
//delay here for 3 seconds, somehow
}
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
}
那么......关于如何在不调用无法将对象返回原始函数的外部Timer函数的情况下实现此目的的任何想法?
谢谢,
答案 0 :(得分:2)
您想要它的方式将使您的整个应用程序滞后3秒,对任何用户输入和外部事件都没有响应。但有可能,当然可以:
import flash.utils.getTimer;
private function createArrayCollection(myObject:Object):ArrayCollection
{
var myArrayCollection:ArrayCollection = new ArrayCollection;
if (globalWaitBoolean)
{
var waitUntil:int = getTimer() + 3000;
// Method getTimer() returns time in ms passed since app start.
// So you just have to wait until it is greater than appointed time.
while (getTimer() < waitUntil)
{
// Do nothing.
}
}
return (myArrayCollection);
}
但是,如果您想以正确方式执行此操作:
import flash.utils.setTimeout;
private function callerMethod():void
{
// Blah blah blah.
// ...
// Finally.
createArrayCollection(sourceData, asyncResult);
}
private function createArrayCollection(myObject:Object, handler:Function):void
{
var result:ArrayCollection = new ArrayCollection;
if (globalWaitBoolean) setTimeout(handler, 3000, result);
else handler(result);
}
private function asyncResult(source:ArrayCollection):void
{
// The rest of your processing code.
}
答案 1 :(得分:1)
正常(同步)代码流在准备好值之前不会返回,因此如果您不想让应用程序执行任何操作,您希望实际等待3秒,请使用@Organis的getTimer()
方法&#39;的答案。如果您要获得异步结果,那么您需要面对并克服更多问题。
首先,您希望何时返回ArrayCollection
实际到达。说到代码设计,异步代码需要大量的假设,线程安全等等,即使AS3 / Flash没有真正的多线程,除非你计算Worker
s,带事件的代码流并不那么明显。所以,无论谁打电话给你的createArrayCollection()
都不能指望它立刻从它返回。所以,谈到你的直接问题,不,如果你想要一个响应式应用,你就不能避免某种类型的计时器。但是你可以使用一种涉及间接返回结果的方法来使用它们。
其次,如果您的应用需要这些请求,是否可能会有来自对象的更多数组集合的同时请求 - 您必须为可能由此引起的任何干扰做好准备。假设您的功能是通过单击按钮触发的 - 如果该按钮在3秒钟内被多次点击该怎么办?
第三,处理代码的实际路由不是异步返回的直接路径。您需要一个回调,一个事件处理程序(本质上是一个半原生的回调),一个定期检查值存在的代码(输入帧处理程序等)或类似的技巧来收集异步返回的值,然后将其转移到任何可以进一步处理它的相关代码。因此,您需要设计一个能够接收复杂数据的接口(源对象转发,向后数组收集),然后针对所有可能的情况和缺陷仔细测试它。
实施所有这些非常漫长的例子,我将尝试以某种方式概述它。 Ler's假设你有一种&#34;服务器&#34;接受数据请求并同步处理(无等待)或异步(等待)的类。它接受类型为&#34; T&#34;的源对象。并提供一个新创建的ArrayCollection
类型的对象,作为参数提供给发送给它的任何回调函数。它还接受延迟(一种简单的方式来显示同步/异步返回将是一个布尔值,但为什么不得到一个int?)作为参数,并保证(在事件模型限制的范围内)在此延迟之后回调将尽快称为。该架构将如下所示:
class Processor {
Dictionary requests; // here all the requests that are delayed will be stored
public function dpr(source:T,callback:Function,delay:int=0):void{...}
// creates requests and stores them
private function syncProcess(source:T):ArrayCollection {...}
// whatever routine you want to get variably delayed
private function processTimeout(e:Event=null):void {...}
// processes events from "setTimeout()" and calls callbacks
}
请注意,异步方法不得不创建三个实体而不是同步实体。首先是请求保持结构(这里是字典),第二个是超时事件处理程序,第三个是您希望在数据准备好时调用的任何回调。代码流将如下所示:
同步调用将导致从类中直接调用回调:request
- &gt; processTimeout
- &gt; syncProcess()
- &gt; callback
。异步调用将通过在Timer::timerComplete
内调用的setTimeout
内的request
事件处理程序调用回调函数,其中最初来自request
的数据存储在requests
中。 / p>
答案 2 :(得分:1)
您可以使用嵌入式/内联函数:
private function createArrayCollection(myObject:Object):ArrayCollection {
var myArrayCollection:ArrayCollection = new ArrayCollection();
if (globalWaitBoolean) {
var milliseconds:int = 3000;
//delay here for 3 seconds
setTimeout(function()
{
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
},
milliseconds);
}
else
{
//Here I do the stuff that uses the info in myObject to figure out what to
//put into the ArrayCollection I want to return
return (myArrayCollection);
}
}
内部函数可以访问外部函数的所有局部变量。