I just made a commit and I want to give some background:

I personally strongly dislike Promises. Promises address a need (namely 
callback hell), but IMO address it poorly. I find Promises unintuitive and 
difficult to use especially when the use case is complex. I have cases where I 
have a literally a chain of 35 “then” calls with various catches mixed in. It’s 
a nightmare to maintain.

Here’s my beefs with Promises
1. You never actually invoke them. You declare a new Promise (or it gets 
spawned for you) and it magically happens on its own. I hate magic.
2. The aforementioned problem makes it very difficult to control *when* the 
promise gets invoked.
3. It’s not very intuitive how/when to resolve and reject promises.
4. Promises lend themselves to nested function calls which I find very hard to 
read.
5. Running many promises and actually dealing with the results is hard and 
cumbersome.
6. Promise.all can help with the above, but what happens if *some* of them 
pass? There’s many different ways that you might want to handle that.
7. There’s very little control of parallel vs serial running of promises.
8. What is the result? Hard to know. I’d really like some strongly typed values 
to make my life easier.
9. How do you deal with progress and promises? It only resolves or rejects. 
AFAIK, fetch has no way to get progress. How dumb is that?

On top of all this, I just find I always need to go back to the spec every time 
I use promises. I find them *very* unintuitive.

So I decided to do something about it. My solution is AsyncTasks.

I created AsyncTasks over two years ago and I’ve been using them in my app 
since then. (My use case was pretty specific to my needs.) I had on my to-do 
list to add some concrete AsyncTasks to Royale for this whole time and I was 
finally inspired to follow through…

I just created three Async classes in Network for HTTP requests and I figured 
now was the time to explain how to use them. ;-)

Basically:
var task: HttpRequestTask = new HttpRequestTask();
task.url = “https://foobaz.com/myapi <https://foobaz.com/myapi>”;
task.done(function(taskReturned:HttpRequestTask):void{
        trace(“task is the same and taskReturned: “ + task == taskReturned);// 
you get the task back in the done callback
        if(task.status == AsyncTask.COMPLETE){
                trace(task.httpResult);
                trace(task.httpStatus);
        } else {// it failed you can get the status to know why
                trace(task.httpStatus);
        }
});
// you need to run it or nothing happens...
task.run();

That’s a single task. You can also pass an array of tasks (of all types) into a 
CompoundAsyncTask or a SequentialAsyncTask.

CompoundAsyncTasks run all the requests in parallel. You can failEarly if you 
want it to complete when the first one errors. Otherwise you have the list of 
all the tasks when it’s done and you can loop through them to do whatever you 
want with the results. You can also get the completed and failed tasks 
separately.

SequentialAsyncTask is the same, but it runs each task when the previous one 
finished. It passes the previous task into the next one’s run method so you can 
chain results.

I added tasks for upload and download progress.

I’d like to create one for multipart and File upload as well, but not today…

IMO this architecture addresses every one of my pet peeves. I find them easy to 
use and reason about. I also just updated them to make it pretty difficult to 
create memory leaks while using them. 

I hope you like it as much as me… ;-)

Harbs

Reply via email to