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
