我在Actionscript中读过有关异步等待的一些内容但实际上并不能真正做到这一点。这是我在课堂上编写的简短版本的代码:
private function getXML():void {
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, loadXML);
xmlLoader.load(new URLRequest("test.xml"));
}
private function loadXML(evt:Event):void {
var xmlData:XML = new XML(evt.target.data);
this.parseResults(xmlData);
}
private function parseResults(resultsInput:XML):void {
this.text = resultsInput.Node.attributes()[0];
}
这是一个标准的get xml,完成后触发一个事件,然后将第一个属性发布到类变量text
中的一个节点。
我想用它调用的函数是:
// assume doSomething("circle") was called
private function doSomething(shape:String):String {
this.getXML();
if (this.text == shape) {
// draw circle
return "Drew circle";
} else {
return "Not a circle in the node";
}
}
问题是我总是得到Not a circle in the node
,因为getXML()的处理步骤执行得比事件可以加载,触发,然后存储到要检查的类变量更快。我已经阅读了从使用匿名函数到等待或使用状态或将事件监听器添加到函数(可能吗?)的所有内容,但我无法正确实现它们(或者不理解如何正确实现)所以有人能给我一个我将如何使用上面的代码执行此操作的示例?
我尝试过但没有效果的事情:
在getXML()中声明一个函数变量,因此在读取xml之前不会执行该函数
var f:Function = function loadXML(evt:Event):void {... etc.
then calling f in getXML
不起作用,我不知道如何在动作中调用函数变量来实现这项工作
声明状态变量xmlLoaderState
in getXML()
if (this.xmlLoaderState == "waiting") {
this.xmlLoaderState = "busy";
}
in parseResults at the end
this.xmlLoaderState = "waiting"
then in doSomething()
while (this.xmlLoaderState == "busy") {}
这个无限循环,我猜它是因为只有一个线程所以循环也阻塞了xmlLoader。
答案 0 :(得分:1)
其他人在这里做出了回应,完美地回答了你的问题,我不知道它去了哪里。
无论如何,由于调用是异步的,因此Flex将启动加载事件,然后继续卡车到下一行。您需要做的是等待Flex从服务调用接收响应,然后您可以引用xml。
这可以通过将“doSomething”代码放在Event.COMPLETE处理程序中来实现。这样你就知道数据已被加载。
答案 1 :(得分:0)
我通过使该函数中的所有参数也为类变量然后使用这些类变量来检查形状是否正确来“解决”参数问题。这是一个非常糟糕的命名空间滥用,但我不知道如何做到这一点。即使我扩充完整事件,我也无法将参数输入到默认的URLLoader类中,这意味着我必须更改内置的URLLoader类以接受自定义参数,这对于看起来像我感觉太多了一个典型的问题。
希望有人出现并告诉我一个更好的解决方案,我会关注它,直到现在这是一个临时解决方案,可以让代码运行。