如何修复 ActionScript 3 (AS3) 中的闭包问题 [英] How to fix closure problem in ActionScript 3 (AS3)

查看:23
本文介绍了如何修复 ActionScript 3 (AS3) 中的闭包问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我尝试加载一些图像,并在它们单独加载后立即将它们放入舞台.但它被窃听,因为只显示最后一张图像.我怀疑这是一个关闭问题.我该如何解决?AS3 中的闭包行为和 Java Script 中的行为不一样吗?

In the code below I'm trying to load some images and put them in the stage as soon as they get individually loaded. But it is bugged since only the last image is displayed. I suspect it's a closure problem. How can I fix it? Isn't the behaviour of closures in AS3 the same as in Java Script ?

var imageList:Array = new Array();
imageList.push({'src':'image1.jpg'});
imageList.push({'src':'image2.jpg'});
var imagePanel:MovieClip = new MovieClip();
this.addChildAt(imagePanel, 0);

for (var i in imageList) {
    var imageData = imageList[i];
    imageData.loader = new Loader();

    imageData.loader.contentLoaderInfo.addEventListener(
        Event.COMPLETE, 
        function() {
            imagePanel.addChild(imageData.loader.content as Bitmap);
            trace('Completed: ' + imageData.src);             
        });

    trace('Starting: ' + imageData.src);
    imageData.loader.load(new URLRequest(imageData.src));   
}

推荐答案

AS3 中的闭包行为与 Java Script 中的行为不一样吗?

Isn't the behaviour of closures in AS3 the same as in Java Script ?

是的,JavaScript 做的事情完全一样.和 Python 一样.还有其他.

Yes, JavaScript does exactly the same thing. As does Python. And others.

尽管您在 'for' 中定义了 'var imageData',但 for 循环不会在这些语言中引入新的作用域;事实上,变量 imageData 被绑定在包含范围内(外部函数,或者在这种情况下它似乎是全局范围).您可以通过在循环执行完毕后查看 imageData 并在其中找到 imageList 的最后一个元素来验证这一点.

Although you define 'var imageData' inside the 'for', for loops do not introduce a new scope in these languages; in fact the variable imageData is bound in the containing scope (the outer function, or in this case it appears to be global scope). You can verify this by looking at imageData after the loop has completed executing, and finding the last element of imageList in it.

所以只有一个 imageData 变量,而不是循环的每次迭代一个.当 COMPLETE 触发时,它进入闭包并读取 imageData 现在的任何值,而不是在定义函数时(*).通常,for 循环将在 COMPLETE 触发点完成,而 imageData 将保存来自最终迭代的最后一个元素.

So there is only one imageData variable, not one for each iteration of the loop. When COMPLETE fires, it enters the closure and reads whatever value imageData has now, not at the time the function was defined(*). Typically the for-loop will have finished by the point COMPLETE fires and imageData will be holding that last element from the final iteration.

(* - 存在早期绑定"语言,在您定义闭包时评估变量的值.但 ActionScript 不是其中之一.)

(* - there exist 'early-binding' languages that will evaluate the variable's value at the point you define a closure. But ActionScript is not one of them.)

可能的解决方案往往涉及使用外部函数来引入新的作用域.例如:

Possible solutions tend to involve using an outer function to introduce a new scope. For example:

function makeCallback(imageData) { return function() {
    imagePanel.addChild(imageData.loader.content as Bitmap);
    trace('Completed: ' + imageData.src);                                                                                                     
} }
...
imageData.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, makeCallback(imageData));

你/可以/把这个内联,但是双重嵌套的函数()开始变得更难阅读了.

You /can/ put this inline, but the doubly-nested function() starts to get harder to read.

另请参阅 Function.bind() 以了解可用于实现此目的的通用部分函数应用程序功能.它很可能成为未来 JavaScript/ActionScript 版本的一部分,同时可以通过原型设计添加到语言中.

See also Function.bind() for a general-purpose partial function application feature you could use to achive this. It's likely to be part of future JavaScript/ActionScript versions, and can be added to the language through prototyping in the meantime.

这篇关于如何修复 ActionScript 3 (AS3) 中的闭包问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆