När du använder ett asynkront dataleverantörsobjekt måste IFilePromise-egenskapen
isAsync
vara
true
och objektet som returneras av metoden
open()
måste implementera gränssnittet IEventDispatcher. Körningen lyssnar efter flera alternativa händelser så att olika inbyggda objekt kan användas som dataleverantör. Till exempel skickas
progress
-händelser av FileStream- och URLStream-objekt, medan
socketData
-händelser skickas av Socket-objekt. Körningen lyssnar efter lämpliga händelser från alla dessa objekt.
Följande händelser styr processen att läsa data från dataleverantörsobjektet:
-
Event.OPEN – Informerar körningen om att datakällan är färdig.
-
ProgressEvent.PROGRESS – Informerar körningen om att det finns tillgängliga data. Körningen kommer att läsa mängden befintliga data från dataleverantörsobjektet.
-
ProgressEvent.SOCKET_DATA – Informerar körningen om att det finns tillgängliga data. Händelsen
socketData
skickas av socket-baserade objekt. För andra objekttyper bör du skicka en
progress
-händelse. (Körningen lyssnar efter båda objekten för att avgöra vilka data som kan läsas.)
-
Event.COMPLETE – Informerar körningen om att alla data har lästs.
-
Event.CLOSE – Informerar körningen om att alla data har lästs. (Körningen lyssnar av den här anledningen efter både
close
och
complete
.)
-
IOErrorEvent.IOERROR – Informerar körningen om att ett fel uppstod när data lästes. Körningen avbryter skapandet av filen och anropar IFilePromise-metoden
close()
.
-
SecurityErrorEvent.SECURITY_ERROR – Informerar körningen om att ett säkerhetsfel har inträffat. Körningen avbryter skapandet av filen och anropar IFilePromise-metoden
close()
.
-
HTTPStatusEvent.HTTP_STATUS – Används av körningen tillsammans med
httpResponseStatus
för att säkerställa att tillgängliga data representerar önskat innehåll, och inte något felmeddelande (till exempel en 404-sida). Objekt som utgår från HTTP-protokollet bör skicka den här händelsen.
-
HTTPStatusEvent.HTTP_RESPONSE_STATUS – Används av körningen tillsammans med
httpStatus
för att säkerställa att tillgängliga data representerar önskat innehåll. Objekt som utgår från HTTP-protokollet bör skicka den här händelsen.
Dataleverantören bör skicka de här händelserna i följande sekvens:
-
open
-händelse
-
progress
- eller
socketData
-händelser
-
complete
- eller
close
-händelse
Obs!
De inbyggda objekten FileStream, Socket, och URLStream skickar automatiskt de rätta händelserna.
I följande exempel skapas ett fillöfte med hjälp av en anpassad, asynkron dataleverantör. Dataleverantörsklassen utökar ByteArray-objektet (för IDataInput-stöd) och implementerar gränssnittet IEventDispatcher. Vid varje timerhändelse genererar objektet en mängd data och skickar en förloppshändelse för att informera körningen om att dessa data finns tillgängliga. När en tillräckligt stor mängd data har producerats skickar objektet en slutförandehändelse.
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.ProgressEvent;
import flash.events.TimerEvent;
import flash.utils.ByteArray;
import flash.utils.Timer;
[Event(name="open", type="flash.events.Event.OPEN")]
[Event(name="complete", type="flash.events.Event.COMPLETE")]
[Event(name="progress", type="flash.events.ProgressEvent")]
[Event(name="ioError", type="flash.events.IOErrorEvent")]
[Event(name="securityError", type="flash.events.SecurityErrorEvent")]
public class AsyncDataProvider extends ByteArray implements IEventDispatcher
{
private var dispatcher:EventDispatcher = new EventDispatcher();
public var fileSize:int = 0; //The number of characters in the file
private const chunkSize:int = 1000; //Amount of data written per event
private var dispatchDataTimer:Timer = new Timer( 100 );
private var opened:Boolean = false;
public function AsyncDataProvider()
{
super();
dispatchDataTimer.addEventListener( TimerEvent.TIMER, generateData );
}
public function begin():void{
dispatchDataTimer.start();
}
public function end():void
{
dispatchDataTimer.stop();
}
private function generateData( event:Event ):void
{
if( !opened )
{
var open:Event = new Event( Event.OPEN );
dispatchEvent( open );
opened = true;
}
else if( position + chunkSize < fileSize )
{
for( var i:int = 0; i <= chunkSize; i++ )
{
writeUTFBytes( 'A' );
}
//Set position back to the start of the new data
this.position -= chunkSize;
var progress:ProgressEvent =
new ProgressEvent( ProgressEvent.PROGRESS, false, false, bytesAvailable, bytesAvailable + chunkSize);
dispatchEvent( progress )
}
else
{
var complete:Event = new Event( Event.COMPLETE );
dispatchEvent( complete );
}
}
//IEventDispatcher implementation
public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
dispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference );
}
public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
{
dispatcher.removeEventListener( type, listener, useCapture );
}
public function dispatchEvent(event:Event):Boolean
{
return dispatcher.dispatchEvent( event );
}
public function hasEventListener(type:String):Boolean
{
return dispatcher.hasEventListener( type );
}
public function willTrigger(type:String):Boolean
{
return dispatcher.willTrigger( type );
}
}
}
Obs!
Eftersom klassen AsyncDataProvider i exemplet utökar ByteArray, kan den inte också utöka EventDispatcher. Klassen använder ett internt EventDispatcher-objekt för att implementera gränssnittet IEventDispatcher och vidarebefordrar IEventDispatcher-metodanropen till det interna objektet. Du bör också utöka EventDispatcher och implementera IDataInput (eller implementera båda gränssnitten).
Den asynkrona implementeringen av IFilePromise är nästan identisk med den synkrona implementeringen. De viktigaste skillnaderna är att
isAsync
returnerar
true
och att metoden
open()
returnerar ett asynkront dataobjekt:
package
{
import flash.desktop.IFilePromise;
import flash.events.ErrorEvent;
import flash.events.EventDispatcher;
import flash.utils.IDataInput;
public class AsynchronousFilePromise extends EventDispatcher implements IFilePromise
{
private var fileGenerator:AsyncDataProvider;
private const fileSize:int = 5000; //size of file data
private var filePath:String = "AsynchronousFile.txt";
public function get relativePath():String
{
return filePath;
}
public function get isAsync():Boolean
{
return true;
}
public function open():IDataInput
{
fileGenerator = new AsyncDataProvider();
fileGenerator.fileSize = fileSize;
fileGenerator.begin();
return fileGenerator;
}
public function close():void
{
fileGenerator.end();
}
public function reportError(e:ErrorEvent):void
{
trace("Something went wrong: " + e.errorID + " - " + e.type + ", " + e.text );
}
}
}