我正在尝试做一些非常简单的事情:编写一个从文本文件中读取文本的函数,并使用AS3以字符串形式返回文本。
功能
public function readData(path:String):String
{
var dataSet:String;
var urlRequest:URLRequest = new URLRequest(path);
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
urlLoader.load(urlRequest);
function urlLoader_complete(evt:Event):void {
dataSet = urlLoader.data;
trace(dataSet)
}
trace(dataSet);
return dataSet;
}
调用函数
var dataString:String = aq.readData("http://example.com/data.txt");
trace(dataString);
此代码在运行时返回空字符串。为什么呢?
修改
好的,我现在看到这不起作用,因为urlLoader是异步操作的。我正在编写一个读取数据文件并对其进行操作的程序。这是否意味着我需要在function urlLoader_complete
内编写我的其余程序?或者我应该暂停程序直到urlLoader
完成?
答案 0 :(得分:3)
在Flash和Flex中,所有网络I / O都是异步的。必须采用这种方式才能避免阻止浏览器。
因此,无法编写直接返回网络读取操作结果的readData()函数。您必须将回调函数传递给readData()函数。当readData()读完数据后,它可以调用回调函数。
例如:
/**
* Asynchronous function to read data as a string. When the data has been read,
* the callback function is called with the result.
*
* @param path the URL to read
* @param callback the function that is called with the result; should take
* one string argument.
*/
public function readData(path:String, callback:Function):void
{
var dataSet:String;
var urlRequest:URLRequest = new URLRequest(path);
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
urlLoader.load(urlRequest);
function urlLoader_complete(evt:Event):void {
dataSet = urlLoader.data;
trace(dataSet);
callback(dataSet);
}
}
以下是您可以从Flex调用该函数的方法:
<mx:Label id="mylabel" />
<mx:Button click="readData('http://www.google.com/',
function(s:String):void {mylabel.text = s})" />
答案 1 :(得分:1)
3年前,这个问题出现在你面前,但是几个小时前我偶然发现了这个问题,并设法让它发挥作用,并想到为什么不分享它。可能已经有了更好的替代方案,但是嘿,我刚刚开始编写Actionscript,所以没有责备:)
首先使用filecounter构建一个Preloader类。构造函数中将有一个numFiles参数,用于保存要加载的文件总数。每次调用complete方法时,都会添加1到filecounter,并且语句将检查是否所有文件都已加载。当numFiles等于计数器时,调用调用类的start()方法。
* Preloader.as *
package
{
import flash.display.Loader;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class Preloader
{
public var urlLoader:URLLoader;
public var response:Array = new Array();
public var callingClass:Object;
public var numFiles:uint;
private var counter:uint;
public function Preloader(callingClass:Object, numfiles:uint)
{
this.callingClass = callingClass;
this.numFiles = numFiles;
}
public function load(name:String):void
{
var request:URLRequest = new URLRequest(name);
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onLoad);
urlLoader.load(request);
}
public function onLoad(event:Event):void
{
response[counter] = event.currentTarget.data;
if(numFiles == counter) {
callingClass.start();
} else {
counter++;
}
}
}
}
调用类中的构造函数方法必须调用所有preload文件,start方法将替换构造函数。请注意,当预加载器加载时,需要引用其调用类和“要加载”文件的总数:
package
{
import flash.display.MovieClip;
import misc.Preloader;
public class Path extends MovieClip
{
public var preloader:Preloader = new Preloader(this, 3); //pass this class and the total number of files
public function Controller()
{
preloader.loadJSON('file1.js');
preloader.loadJSON('file2.js');
preloader.loadJSON('file3.js');
}
public function start():void
{
trace(preloader.response[0]); //Get first file contents
}
}
}