Als u een asynchroon gegevensaanbiederobject gebruikt, moet de eigenschap
isAsync
van IFilePromise zijn ingesteld op
true
en moet het object dat wordt geretourneerd door de methode
open()
de IEventDispatcher-interface implementeren. Tijdens runtime wordt er geluisterd of een aantal alternatieve gebeurtenissen plaatsvinden, zodat verschillende ingebouwde objecten als gegevensaanbieder kunnen worden gebruikt.
progress
-gebeurtenissen worden bijvoorbeeld verzonden door FileStream- en URLStream-objecten, terwijl
socketData
-gebeurtenissen worden verzonden door Socket-objecten. Tijdens runtime wordt er geluisterd of al deze objecten de juiste gebeurtenissen verzenden.
Het lezen van gegevens in het gegevensaanbiederobject wordt door de volgende gebeurtenissen aangestuurd:
-
Event.OPEN - Meldt dat de gegevensbron klaar is.
-
ProgressEvent.PROGRESS - Meldt dat de gegevens beschikbaar zijn. Tijdens runtime wordt de hoeveelheid beschikbare gegevens in het gegevensaanbiederobject gelezen.
-
ProgressEvent.SOCKET_DATA - Meldt dat de gegevens beschikbaar zijn. De gebeurtenis
socketData
wordt verzonden door op sockets gebaseerde objecten. Voor andere typen objecten moet u een
progress
-gebeurtenis verzenden. (Tijdens runtime wordt er geluisterd wanneer beide gebeurtenissen plaatsvinden, zodat er kan worden bepaald wanneer er gegevens kunnen worden gelezen.)
-
Event.COMPLETE - Meldt dat de gegevens helemaal gelezen zijn.
-
Event.CLOSE - Meldt dat de gegevens helemaal gelezen zijn. (Tijdens runtime wordt er geluisterd wanneer
close
en
complete
hiervoor plaatsvinden.)
-
IOErrorEvent.IOERROR - Meldt dat er zich bij het lezen van de gegevens een fout heeft voorgedaan. Het maken van een bestand wordt afgebroken en de methode
close()
van IFilePromise wordt aangeroepen.
-
SecurityErrorEvent.SECURITY_ERROR - Meldt dat er zich een beveiligingsfout heeft voorgedaan. Het maken van een bestand wordt afgebroken en de methode
close()
van IFilePromise wordt aangeroepen.
-
HTTPStatusEvent.HTTP_STATUS - Wordt samen met
httpResponseStatus
gebruikt om ervoor te zorgen dat de beschikbare gegevens de gewenste inhoud representeren en niet een foutbericht (zoals een 404-pagina). Objecten die op het HTTP-protocol zijn gebaseerd, moeten deze gebeurtenis verzenden.
-
HTTPStatusEvent.HTTP_RESPONSE_STATUS - Wordt samen met
httpStatus
gebruikt om ervoor te zorgen dat de beschikbare gegevens de gewenste inhoud representeren. Objecten die op het HTTP-protocol zijn gebaseerd, moeten deze gebeurtenis verzenden.
De gegevensaanbieder moet deze gebeurtenissen in de volgende volgorde verzenden:
-
De gebeurtenis
open
-
De gebeurtenis
progress
of de gebeurtenis
socketData
-
De gebeurtenis
complete
of de gebeurtenis
close
Opmerking:
De ingebouwde objecten FileStream, Socket en URLStream verzenden automatisch de juiste gebeurtenissen.
In het volgende voorbeeld wordt een bestandsbelofte gemaakt met een aangepaste asynchrone gegevensaanbieder. De gegevensaanbiederklasse biedt ByteArray uit (voor de ondersteuning voor IDataInput) en implementeert de IEventDispatcher-interface. Bij elke timer-gebeurtenis genereert het object een hoeveelheid gegevens en verzendt het object een progress-gebeurtenis om tijdens runtime te melden dat de gegevens beschikbaar zijn. Als er genoeg gegevens zijn gegenereerd, verzendt het object een complete-gebeurtenis.
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 );
}
}
}
Opmerking:
Omdat de AsyncDataProvider-klasse in het voorbeeld ByteArray uitbreidt, kan deze klasse niet tevens EventDispatcher uitbreiden. Om de IEventDispatcher-interface te implementeren, gebruikt de klasse een intern EventDispatcher-object en stuurt de IEventDispatcher-methode aanroepen door naar dat interne object. U kunt eventueel ook EventDispatcher uitbreiden en IDataInput implementeren (of beide interfaces implementeren).
De asynchrone IFilePromise-implementatie is bijna identiek aan de synchrone implementatie. De belangrijkste verschillen zijn dat
isAsync
true
retourneert en dat de methode
open()
een asynchroon gegevensobject retourneert:
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 );
}
}
}