PDA

Просмотр полной версии : Как вернуть строку из URLLoader


vvk80
28.05.2007, 15:45
Уважаемые форумчане, помогите мне пожалуйста!

Я, наверное, чего-то не понимаю, но почему в следующем коде я никак не могу получить строку на выходе???

function textLoader():String
{
var loader:URLLoader = new URLLoader();
var resultText: String = "";
var request:URLRequest = new URLRequest("Texts\\umatch35.txt");
try
{
loader.load(request);
}
catch (error:Error)
{
trace("Unable to load requested document.");
}
loader.addEventListener(Event.COMPLETE, completeHandler);

function completeHandler(event:Event):void
{
resultText = loader.data;
//trace(resultText);

//
}
//trace(resultText);
return resultText;

}
судя по сообщениям trace,сначала обрабатывается команда return, а только потом срабатывает функция completeHandler... В итоге resultText = пусто. Народ, как полечить или может быть я сам дурак? Тогда подскажите где?

Заранее спасибо!

miramax
28.05.2007, 15:56
всё правильно.
Функция textLoader, не дождавшись окончания загрузки возвращает ничего.

Загрузка файла происходит не моментально, а Action Script исполняется в одном потоке.
Функция completeHandler будет вызвана по окончании загрузки файла.

vvk80
28.05.2007, 16:00
всё правильно.
Загрузка файла происходит не моментально, а
Action Script исполняется в одном потоке.
Функция completeHandler вызывается не моментально, а по окончании загрузки файла.

Спасибо! Это кстати фигово! Но как мне все-таки строку то вернуть, я не хочу какждый раз эту функцию копировать (у меня порядка 20-ти лоадеров получится). Это вообще нарушит всякие принципы OOP программирования... Как мне все-таки строку вернуть? Ну не таймер же все-таки ставить? Наверняка месть дргйо способ..:eek:

miramax
28.05.2007, 16:03
Зачем копировать?
Где нарушается ООП?
Для обработки данные нужно сначала загрузить.

etc
28.05.2007, 16:06
vvk80, отредактируйте свой пост и оформите код тегами .

vvk80
28.05.2007, 16:06
Зачем копировать?
Где нарушается ООП?
Для обработки данные нужно сначала загрузить.

Наверное я туплю... Я понимаю, что данные надо сначала загрузить... Но подскажите мне, пожалуйста, как мне выкрутиться из текущей ситуации. Направьте меня в нужное русло!

Заранее спасибо!

etc
28.05.2007, 16:10
Загрузка данных происходит асинхронно с кодом. Их невозможно вернуть сражу же после вызова load.

miramax
28.05.2007, 16:13
Ну у тебя всё верно, кроме функции, которой ты захотел всё заинкапсулировать и моментально возвратить. Общий план такой:var loader:URLLoader = new URLLoader();
loader.load(new URLRequest('text.txt'));
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(e:Event):void
{
trace(loader.data)
}

vvk80
28.05.2007, 17:02
Ну у тебя всё верно, кроме функции, которой ты захотел всё заинкапсулировать и моментально возвратить. Общий план такой:var loader:URLLoader = new URLLoader();
loader.load(new URLRequest('text.txt'));
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(e:Event):void
{
trace(loader.data)
}
Спасибо,miramax!
Пока обойдемся без инкапсуляции;) А потом я туда таймер запихну, который будет смотреть, когда переменная заполнится и возвращать ее... Хотя таймер ресурсы жрет дико... я тут решил картинки подвигать по таймеру, так у меня 100% загрузка процессора

miramax
29.05.2007, 02:26
Какой таймер?
completeHandler это всё что нужно.
А чего-то двигать по экрану нужно по событию Event.ENTER_FRAME ...
Посмотри внимательнее примеры в хелпе.

7thsky™
29.05.2007, 10:17
Спасибо,miramax!
Пока обойдемся без инкапсуляции;) А потом я туда таймер запихну, который будет смотреть, когда переменная заполнится и возвращать ее... Хотя таймер ресурсы жрет дико... я тут решил картинки подвигать по таймеру, так у меня 100% загрузка процессора


В АС3 просто не возможно сделать так чтобы одна функция посылала и возвращала результат, даже не пытайтесь - просто потратите время.

vvk80
14.06.2007, 20:08
Решение проблемы теоретически найдено (на тестовом примере вроде работает):

package HelperClasses
{
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.net.*;

public class LoadText extends URLLoader
{
//private variables
private var _sTarget:String;
private var resultText:String;
private var loader:URLLoader;

private var dataWritten:Event;

public function LoadText (target:String):void
{
//constructor
this._sTarget = target;
textLoader();
}

private function textLoader():void
{
loader = new URLLoader();
var resultText: String = "";
var request:URLRequest = new URLRequest(target);
try
{
loader.load(request);
}
catch (error:Error)
{
trace("Unable to load requested document.");
}
loader.addEventListener(Event.COMPLETE, completeHandler);
//trace(resultText);
}
private function completeHandler(event:Event):void
{
resultText = loader.data;
dataWritten = new Event("dataWritten", true);
dispatchEvent(dataWritten);
//trace("Tracing complate Handler " + resultText);
//
}
public function get outputText():String
{
return resultText;
}
public function getOutPutText():void
{
trace(resultText);
}
}
}

ну в основном файле:


var myText:LoadText = new LoadText("Texts\\sample.txt");
var myVar:String;
myText.addEventListener("dataWritten", onDataReceived);
function onDataReceived(event:Event):void
{
myVar = myText.outputText;
trace("!!!!!!!!!" + myVar);
}


конечно, значение переменной будет видно только в рамках функции onDataReceived, но все равно меня это устроит, так как таким образом я могу вынести функциональность загрузки файла в отдельный класс...

Кстати, если я вдруг написал откровенную чушь, прошу поправить... я начинающий, так что буду рад любым комментам :)

silin
14.06.2007, 22:47
значение переменной будет видно везде, но только после события dataWritten..
насчет выноса функциональность загрузки файла в отдельный класс и вещания своего события: не очень понятно что это тебе дает..
загрузка и так вынесена в отдельный класс (URLLoader), можно его просто расширить, привязав экземпляр к конкретному урлу в конструкторе:
package {
import flash.net.URLLoader;
import flash.net.URLRequest;
public class TextLoader extends URLLoader {

function TextLoader(url:String){
load(new URLRequest(url));
}
}
}
var myText:TextLoader=new TextLoader("sample.txt");
myText.addEventListener(Event.COMPLETE,onDataReceived);
function onDataReceived(e:Event):void{
trace("!!!!!!!!!"+ myText.data);
}