First, I want to mention, I understand how the Firebase onDisconnect method works in JavaScript. It tells the server what to do once the user is disconnected, in advance.
Now, I am using AS3. How should I tell the server the same thing as achieved by the 'onDisconnect' method?
When I tried debugging the code in JavaScript, it doesn't seem to send something to the server.(or maybe i am wrong).
Sample code in JavaScript:
userRef.on('value', function(snapshot) {
if (snapshot.val()) {
userRef.onDisconnect().remove(); //this line does the magic
}
});
What is being done by the onDisconnect method which tells the server what to do? What is the equivalent code if written in AS3?
EDITED:
The code in AS3, as reference by here, it works for Realtime Database.
private var myStream:URLStream;
private function loadLiveFeed():void
{
var header:URLRequestHeader = new URLRequestHeader("Accept", "text/event-stream");
var request:URLRequest = new URLRequest("https://<YOUR-PROJECT-ID>.firebaseio.com/breakingnews.json");
request.requestHeaders.push(header);
myStream:URLStream = new URLStream();
myStream.addEventListener(ProgressEvent.PROGRESS, progress);
myStream.load(request);
}
private function progress(event:ProgressEvent):void
{
var message:String = myStream.readUTFBytes(myStream.bytesAvailable);
trace(message);
}
The code you shared accesses the Firebase Database through its REST API:
new URLRequest("https://<YOUR-PROJECT-ID>.firebaseio.com/breakingnews.json");
This means that it is using a connectionless method to interact with the database. Unfortunately that also means that there is no way to register an onDisconnect() handler, since it would essentially have to fire between any two HTTP calls that you make.
No time to answer this, but you'd have to reverse engineer the communication. Under the hood, it's all just HTTP (or similar) as can be seen in the As3 code. To know what's going on exactly, get a working example code in JavaScript that contains the magic line you are curious about, then execute it in the browser. All requests can be monitored in the developer tools of the browser. You should be able to identify what's being sent.
Also, it's JavaScript, which means you have to have the source code which you can simply read. It might be minified and/or obfuscated, but maybe you can find a readable one.
With the knowledge of what the bare requests look like, you can then implement an API of your own in any language that's capable of performing the necessary network communication.
Related
I recently came across this issue. For a project I'm working on, we were using .bind() way too often and it actually hit the performance quite hard considering that we only have 16ms for the rendering loop to do things.
So I did some jsperf and noticed that calling a bound function (besides of the extra garbage) is way slower than calling an unbound function or using .call on a function.
I literally changed every piece of code to avoid bindings and to use .call/.apply instead. Ding this i not only spawned less functions but also increased the performance of my app a great deal.
However, I was unsatisfied with this and wrote a new way of binding functions.
https://github.com/SebastianNette/FastBind
This is overwriting the native bind method with a .call/.apply approach.
And it runs 96% faster.
Doing some testings on nodejs is came to these results:
Calling a bound function is 20 times slower than calling an unbound function.
Calling a bound function with my own approach takes only 2 times the time of the unbound call.
So I was wondering what is wrong with the native binding function. Why does it behave like that? And which would be the best way to deal with that issue.
Most of my app code is now written like that:
var scope = this;
this.boundFn = function(a,b,c) { return scope.fn(a,b,c); };
Or even
this.callback = fn;
this.context = context;
this.callback.call(this.context);
I do prefer the latter because it doesn't spawn any new functions. However, sometimes I just do have to bind. (handlers, timers, etc).
My educated guess is that it makes a clone of the object you are using but replaces the underlying prototype of object. Instead of using a generic precompiled object from the page rendered code it now has to take two things:
The passed variable thats to be come this. analyse it, clone it. then inject the specified function thats to be called into the new object. Then execute the function in the new object. afterwards if no longer called clean it up.
The more complex and more scoping loops an object has the long the bind will take because the engine needs to traverse the scope tree of all functions and parameters to see what needs to be copied.
You are already using scoping, which I strongly advice. It is less memory intense and the engine does not have to copy the objects and then call the functions. And you get the added benefit that you can access properties from both objects.
In my experience binding is never truly needed. Just use setters and getters for properties, otherwise the scoped variables won't always change in the main object.
Take for example this snippet
function domagic() {
this.myproperty = "Hello ";
}
domagic.prototype = {
perform:function(){
var that = this;
var hello = "World";
setTimeout(function(){
// this in this contect is whatever runs timeout. not domagic
// I use this for jQuery and my own objects to get best
// of both worlds, but I always post a comment in a scope
// to remind myself what this and that refers to.
window.alert(that.myproperty+hello);
that.set("Goodbye ");
},2000);
},
set : function(what) {
this.myproperty = what;
}
};
magic = new domagic();
magic.perform();
setTimeout(function(){magic.perform();},2000);
I have this program, that needs to load a text file, which it can do, but since everything is multi-threaded on AS3, it continues with the program even though its not loaded. Like, if I was to make a function that loads the text, and then have it return the loaded text, it will always return "undefined". I have to add an event listener for when it's done, but the way I have to handle the returning of the text is awkward. Is there any way to make the program just wait, or do nothing until it's loaded?
It sounds like what you're looking for is for the data to load synchronously so that you can just make the loading call and have it return right away, like so:
# (this actually is not actionscript)
fileDataContents = open("file.txt", "r");
then have the fileDataContents immediately available to use.
By design this is not how flash works.
Loading external data in flash is not multithreaded, but rather asynchronous. One very good reason why synchronous loading is not done is that it causes blocking/locking of the program during the operation potentially resulting in a poor user experience.
Take for example, if this is loading a file over the web: what if the user's internet connection had just cut out/hiccupped or had been moved/deleted/modified suddenly on the server? Or what if the file is moderately sized but the user was on dial-up?
This is out of your control in most cases and the resulting behaviour may be that it causes flash to "forever" freeze in the user's browser window as it tries to load, possibly taking down the whole browser with it, ultimately ending in a poor user experience. By blocking/locking the program in that loop you would have no way to recover or respond to the user appropriately.
No, you can't.
Listening for the COMPLETE event like you have now is the correct way to wait and continue the application flow once done. I can't see how this would become awkward - I suggest updating your question to include information about what's making you uncomfortable about the event system so that I can help you from there.
Perhaps you're just not structuring your code in a way that works well with the event system. Here is how you can set up a very clean, straightforward way of loading some data and starting up the application once done.
Here's the document class, which can be used purely as a channel to load your text data which will be forwarded on to a fresh instance of the actual Application class:
public class Main extends Sprite
{
private var _application:Application;
private var _loader:URLLoader;
public function Main()
{
var fileUrl:URLRequest = new URLRequest("file.txt");
_loader = new URLLoader(fileUrl);
_loader.addEventListener(Event.COMPLETE, _textLoaded);
}
private function _textLoaded(e:Event):void
{
_loader.removeEventListener(Event.COMPLETE, _textLoaded);
// Load the main Application with the required text data.
_application = new Application( _loader.data );
}
}
And then your Application, which you can consider your central class.:
public class Application
{
public function Application(textData:String)
{
// Here we have access to the required text, and we can
// begin preparing the main Application.
trace(textData);
}
}
I'm trying to fill some data from an xml feed we made into my Flash movie. The main action of this is in the constructor for MediaElementJS's .as file.
Anyway, the main problem is that I keep reading there is no way to load a URL synchronously in AS3 (which i still find hard to believe). This constructor calls both parse('url') and a function addEventListener(EVENT.ADDED_TO_STAGE, initializeAds);
Now the ads need info from the XML but the XML aint ready yet. I tried to call the ads at the end of the XML parser when I knew it would be prepped but it messes them up and the ad values never change from their defaults..
Oh wherefor art thou actionscript locking mechanism..
So is there anyway to preload data from a URL?
CODE:
public function LoadXML(e:Event):void
{
removeEventListener(Event.COMPLETE, LoadXML);
var xmlData:XML = new XML(e.target.data);
episodeData.pre.type = xmlData.episode.pre.ad.#type;
episodeData.pre.url = xmlData.episode.pre.ad.text();
episodeData.video = Number(xmlData.episode.video.#id); /*************** I CAN'T REMEMBER ***********/
episodeData.pageTitle = xmlData.episode.video.#pagetitle;
episodeData.title = xmlData.episode.video.#title;
episodeData.source = xmlData.episode.video.source.text();
episodeData.post.type=xmlData.episode.post.ad.#type;
episodeData.post.url=xmlData.episode.post.ad.text();
episodeData.nextEpisode=xmlData.episode.post.nextepisode.text(); //if not empty redirect to this
xmlLoading = false;
//THIS IS WHERE I TRIED TO CALL THE FUNCTION I NEED TO LOAD LATER
}
public function parse()
{
var xmlLoader:URLLoader = new URLLoader();
//var xmlData:XML = new XML();
xmlLoader.load(new URLRequest(rootURL + '/episode.aspx?associd=' + _episode));
//xmlLoader.addEventListener(Event.COMPLETE, processXML);
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
}
I've tried it with a static URL address and whatnot of course but no dice.
The code in the constructor works if I dynamically assign a static value but if I try chaining to events together to get the dynamic value and dynamic assignment it crunches.
In the constructor, definitely runs both by themselves:
parse();
// Google IMA EventListener
addEventListener(Event.ADDED_TO_STAGE, initialize);
Loading URLs is always asynchronous, so add the event listener in the response function for the URL loader.
Now your question sounds like you tried that but had some problem, so post that code and let us take a look.
Edit START
When I have multiple asynchronous calls that happen and I need something to happen after both of them are done I usually use booleans to store if each one has happened yet, then in a third function they both call I check both the booleans.
Here's how I'd do that:
protected function viewnavigatorapplication1_preinitializeHandler(event:FlexEvent):void
{
var loader1:Loader = new Loader();
var loader2:Loader = new Loader();
loader1.addEventListener(Event.COMPLETE, loader1_completeHandler);
loader1.load(new URLRequest("http://www.whitehouse.gov"));
loader2.addEventListener(Event.COMPLETE, loader2_completeHandler);
loader2.load(new URLRequest("http://www.nasa.gov"));
}
private function loader1_completeHandler():void
{
loader1Done = true;
//Maybe do some stuff here
moveOn();
}
private function loader2_completeHandler():void
{
loader2Done=true;
//Maybe do some stuff here
moveOn();
}
private function moveOn():void
{
if(!loader1Done||!loader2Done)
return;
//Do whatever needs to be done once both asynchronous events have completed
}
If this isn't your problem I think you need to provide more of the code in place of the comments that indicate other things happen, because it is a bit unclear.
For example I'm not sure what you mean by "The code in the constructor works if I dynamically assign a static value but if I try chaining to events together to get the dynamic value and dynamic assignment it crunches." Also since there's no example of the data or what the rootURL is there's no way to debug from here to understand what's going wrong.
Since there's no error we would need to be able to re-compile some portion of your code locally to give any better feedback.
Edit END
Blocking or synchronous calls are a horrible idea with regard to network communications due to the lack of reliability of networks and/or servers. If a front end application locked up to wait for a response before doing any other processing it would result in a horrible user experience, this is why there is no synchronous remote calls.
What happens with a synchronous call when the server bombs out, the client remains locked even though no response will result, the user can't interact with anything else in the front-end because it's waiting for said response which will never come? It's much better that remote calls of any sort are done in an asynchronous fashion, the same is true with local disk access in Java (or otherwise) where using asynchronous non-blocking calls is generally a better way to go to allow the other processes within an application to continue regardless of the state or use on the disk.
What you're doing should work just fine, you make a call to a remote service, it responds with some result and hits your "listener" or "callback" function then you want to do something with the results you can call another function, and the data is there.
It sounds to me like the only thing that's not happening is updates after the fact aren't being reflected in the UI, this is probably due to a lack of Bindable metadata/event dispatching for the properties. Have you inspected the result in the event that returns, have you put breakpoints in the method that is meant to be called after the data has returned? What you're doing is completely possible and it even looks like you have most of it right, but there's definitely something your doing wrong that's resulting in you not being able to make this work. If you can explain the behavior a bit clearer that will help, also what do you do here:
//THIS IS WHERE I TRIED TO CALL THE FUNCTION I NEED TO LOAD LATER
I am working with URLLoader and URLRequest in this case.
I have two buttons. One listens for the mouse click event and then runs the following function (less code not applicable to this question):
function loadURL (e:MouseEvent):void {
....
var myRequest:URLRequest=new URLRequest("*URL*");
myRequest.method=URLRequestMethod.POST;
myRequest.data=postVars;
var myLoader:URLLoader = new URLLoader();
myLoader.load(myRequest);
....
}
The other button, when clicked, calls another function, say resetAll, that then resets the "session" by clearing out all the current variables and canceling anything currently in progress. Within that function I want to call myLoader.close(myRequest); but myLoader is not accessible from within resetAll.
In this case, should I declare var myRequest:URLRequest=new URLRequest("*URL*"); and var myLoader:URLLoader = new URLLoader(); outside of the function even if I do not need them yet?
I think I am missing some common sense knowledge of AS3 here, but not sure what it is. It would be appreciated if someone could fill me in on best practice in this case.
You can declare URLLoader variable globally and use local declaration or URLRequest variable.
URLRequest is anyway you have to recreate for every new requests, declaring them locally would be more safer for GC to collect it after its use.
URLLoader makes no sence re creating everytime, you can just pass new URLReqest object into Load method everytime you want to load something from server.
if this function is executed only once, you can use the variables from inside the function.
if this function is executed more then once in the life-time of the application you should declare the variables once and then only reconfigure or reinstantiate them.
Another thing, if you need to use those variables outside the function then you should of course declare them globally. (resetAll)
In some cases, closures are very useful. (Especially, for handling events or for controlling asynchronous codes.)
You can keep all the references of local variables at a time.
But when the source code of closures goes huge in the function, you should think about moving them into another class.
Here is an example
Closure Example - wonderfl build flash online
One thing you may think is the cost of the closures.
Executing closures costs much more than usual codes but it's negligible for ordinal cases.
I have a large application that needs to ensure that various items are loaded (at different times, not just at startup) before calling other routines that depend on said loaded items. What i find problematic is how my architecture ends up looking to support this: it is either littered with callbacks (and nested callbacks!), or pre populated with dozens of neat little
private function SaveUser_complete(params:ReturnType):void
{
continueOnWithTheRoutineIWasIn();
}
and so forth. Right now the codebase is only perhaps 2500 lines, but it is going to grow to probably around 10k. I just can't see any other way around this, but it seems so wrong (and laborious). Also, i've looked into pureMVC, Cairngorm, and these methods seem equally tedious,except with another layer of abstraction. Any suggestions?
Well asynchronous operations always have this affect on code bases, unfortunately there's not really a lot you can do. If your loading operations form some sort of 'Service' then it would be best to make a IService interface, along with the appropriate MVC Style architecture and use data tokens. Briefly:
//In your command or whatever
var service:IService = model.getService();
var asyncToken:Token = service.someAsyncOperation(commandParams);
//some messaging is used here, 'sendMessage' would be 'sendNotification' in PureMVC
var autoCallBack:Function = function(event:TokenEvent):void
{
sendMessage(workOutMessageNameHere(commandParams), event.token.getResult());
//tidy up listeners and dispose token here
}
asyncToken.addEventListener(TokenEvent.RESULT, autoCallBack, false, 0, true);
Where I have written the words 'workOutMessageNameHere()' I assume is the part you want to automate, you could either have some sort of huge switch, or a map of commandParams (urls or whatever) to message names, either way best get this info from a model (in the same command):
private function workOutMessageNameHere(commandParams):String
{
var model:CallbackModel = frameworkMethodOfRetrivingModels();
return model.getMessageNameForAsyncCommand(commandParams);
}
This should hopefully just leave you with calling the command 'callService' or however you are triggering it, you can configure the callbackMap / switch in code or possibly via parsed XML.
Hope this gets you started, and as I've just realized, is relevant?
EDIT:
Hi, just had another read through of the problem you are trying to solve, and I think you are describing a series of finite states, i.e. a state machine.
It seems as if roughly your sequences are FunctionState -> LoadingState -> ResultState. This might be a better general approach to managing loads of little async 'chains'.
Agreeing with enzuguri. You'll need lots of callbacks no matter what, but if you can define a single interface for all of them and shove the code into controller classes or a service manager and have it all in one place, it won't become overwhelming.
I know what you are going through. Unfortunately I have never seen a good solution. Basically asynchronous code just kind of ends up this way.
One solution algorithm:
static var resourcesNeededAreLoaded:Boolean = false;
static var shouldDoItOnLoad:Boolean = false;
function doSomething()
{
if(resourcesNeededAreLoaded)
{
actuallyDoIt();
}
else
{
shouldDoItOnLoad = true;
loadNeededResource();
}
}
function loadNeededResource()
{
startLoadOfResource(callBackWhenResourceLoaded);
}
function callBackWhenResourceLoaded()
{
resourcesNeededAreLoaded = true;
if(shouldDoItOnLoad)
{
doSomething();
}
}
This kind of pattern allows you to do lazy loading, but you can also force a load when necessary. This general pattern can be abstracted and it tends to work alright. Note: an important part is calling doSomething() from the load callback and not actuallyDoIt() for reasons which will be obvious if you don't want your code to become out-of-sync.
How you abstract the above pattern depends on your specific use case. You could have a single class that manages all resource loading and acquisition and uses a map to manage what is loaded and what isn't and allows the caller to set a callback if the resource isn't available. e.g.
public class ResourceManager
{
private var isResourceLoaded:Object = {};
private var callbackOnLoad:Object = {};
private var resources:Object = {};
public function getResource(resourceId:String, callBack:Function):void
{
if(isResourceLoaded[resourceId])
{
callback(resources[resourceId]);
}
else
{
callbackOnLoad[resourceId] = callBack;
loadResource(resourceId);
}
}
// ... snip the rest since you can work it out ...
}
I would probably use events and not callbacks but that is up to you. Sometimes a central class managing all resources isn't possible in which case you might want to pass a loading proxy to an object that is capable of managing the algorithm.
public class NeedsToLoad
{
public var asyncLoader:AsyncLoaderClass;
public function doSomething():void
{
asyncLoader.execute(resourceId, actuallyDoIt);
}
public function actuallyDoIt ():void { }
}
public class AsyncLoaderClass
{
/* vars like original algorithm */
public function execute(resourceId:String, callback:Function):void
{
if(isResourceLoaded)
{
callback();
}
else
{
loadResource(resourceId);
}
}
/* implements the rest of the original algorithm */
}
Again, it isn't hard to change the above from working with callbacks to events (which I would prefer in practise but it is harder to write short example code for that).
It is important to see how the above two abstract approaches merely encapsulate the original algorithm. That way you can tailor an approach that suites your needs.
The main determinants in your final abstraction will depend on:
Who knows the state of resources ... the calling context or the service abstraction?
Do you need a central place to acquire resources from ... and the hassle of making this central place available all throughout your program (ugh ... Singletons)
How complicated really is the loading necessities of your program? (e.g. it is possible to write this abstraction in such a way that a function will not be executed until a list of resources are available).
In one of my project, I build custom loader which was basically wrapper class. I was sending it Array of elements to load and wait for either complete or failed event(further I modified it and added priority also). So I didn't have to add so many handlers for all resources.
You just need to monitor which all resources has been downloaded and when all resources complete, dispatch a custom event-resourceDownloaded or else resourcesFailed.
You can also put a flag with every resource saying it is necessary or compulsory or not, If not compulsory, don't throw failed event on failing of that resource and continue monitoring other resources!
Now with priority, you can have bunch of file which you want to display first, display and continue loading other resources in background.
You can do this same and believe me you'll enjoy using it!!
You can check the Masapi framework to see if it fulfills your needs.
You can also investigate the source code to learn how they approached the problem.
http://code.google.com/p/masapi/
It's well written and maintained. I used it successfully in a desktop RSS client I developed with Air.
It worked very well assuming you pay attention to the overhead while loading too many resources in parallel.