从同步流到异步流两难

时间:2013-02-18 16:23:33

标签: actionscript-3 air

作为一名PHP程序员,我非常习惯于程序流逐行进行的事实,如果我调用function1()必须返回一些值,我知道程序不会继续,直到该函数返回。 / p>

现在,我正在使用AIR开发AS3应用程序,我需要下载一些图像,如果满足某些条件,不知道有多少,所以即时通讯使用像这样的:

for (var w:int=0; w < newData_array[2]['content'].length; w++ ) {
    for (var j:int=0; j < oldData_array[2]['content'].length; j++ ) {
        if((oldData_array[2]['content'][j]['id'] == newData_array[2]['content'][w]['id']) &&  (oldData_array[2]['content'][j]['last_mod'] != newData_array[2]['content'][w]['last_mod'])){
            //need to download a image...
        }
    }       
}

正如您所看到的,我只是比较每个数组中的每个元素( newData_array oldData_array )。如果条件满足,我需要下载一些东西,因为我正在使用 URLloader ,并且如你所知这个函数是异步的,添加一个监听器,当下载完成时会触发一个事件,问题很清楚,因为urlloader不会停止for循环(就像我期望的PHP语言)我只是要下载一堆图像同时创建一个灾难,因为我不知道什么时候保存。因此我需要任意使用听众,但由于我不习惯这种程序,所以我很笨拙。

我对保存到磁盘的例程不感兴趣,那部分已经完成了,我只是想了解我应该如何构建这个算法来使其工作。

3 个答案:

答案 0 :(得分:0)

这让我很生气,但是人们必须意识到你不能对内存中不存在的东西做些什么,而这些加载操作可能需要相当长的时间。作为单线程堆栈,Flash Player的加载操作将要求整个接口在加载期间冻结(如果仅限于循环)。

显然,循环可用的数据决定了你对图像的处理方式。我一直在使用的解决方案是创建一个启动加载的自定义加载函数,并返回一个代理图像。你的循环得到一个容器,你可以自由地将你的图像放在你想要的地方。

与此同时,您的加载程序侦听器已跟踪活动图像加载及其关联代理。加载后,交换图像。

你的循环看起来像这样......

for (var w:int in newData_array[2]['content']) {
    for (var j:int in oldData_array[2]['content']) {
        if ((oldData_array[2]['content'][j]['id'] == newData_array[2]['content'][w]['id']) && (oldData_array[2]['content'][j]['last_mod'] != newData_array[2]['content'][w]['last_mod'])){
            var proxy:MovieClip = loadImage("image/path.jpg");
            // Do stuff to proxy.
        }
    }    
}

你的函数+监听器看起来像这样......

var proxies:Object = {};
function loadImage(path:String):MovieClip {
    // load Image
    var proxy:MovieClip = new MovieClip();
    proxies.path = proxy;

    // Load Image
}

function imageLoaded(e:Event):void {
    // Once loaded, use the filename as the proxy object's key to find the MovieClip to attach the image.
    proxies[e.data.loaderInfo.filename].addChild(e.data);
}

这只是我的头脑,所以你需要找到实际的变量名,但我希望这是有道理的。

答案 1 :(得分:0)

我不确定我是否理解你的问题,但在我看来你只需在内循环中添加相应的监听器。

 //take care this is pseudocode

 var parent = ... // some stage object
 for (var w:int=0; w < size1; w++ ) {
     for (var j:int=0; j < size2; j++ ) {
         if(some_condition){
             request = new URLRequest(getNextImagePath();
             urlLoader = new URLLoader();
             urlLoader.addEventListener(Event.COMPLETE, onComplete);
             urlLoader.load(request);
         }
     }       
 }

 function onComplete(event:Event) {
     parent.addChild(createImageFromData(this.data));
 }

答案 2 :(得分:0)

我使用第三方库解决了这个问题,而第三方库非常适合处理这个问题。

https://github.com/arthur-debert/BulkLoader