Yeah, Observables have a bit of magic. And most of rxjs is a bit much, sometimes.
The equivalent of your example (JS only), in Observables in Angular, for example, would be: var sub:Subscription = httpclient.get("https://foobaz.com/myapi", {responseType: 'text'}) .subscribe( results => done(results), error => fault(error) ); ... sub.unsubscribe(); And done() and fault() can be anonymous functions (and the "sub" variable is optional). And you can cancel and do a few other things. BehaviorSubject is also nice, in that it lets you have more control over things. Not a task system, obviously. On 10/24/2021 11:46 PM, Harbs wrote: > async/await makes things both better and worse. It lends itself to less > spaghetti code at the price of more magic. The chaining problems still exist > with async/await AFAIK. > > I conceptually like the idea of Observables, but it’s quite a world of its > own. It has a pretty large learning curve and is overkill for any use case > I’ve personally had. > > AsyncTasks is much less ambitious. It aims to do one thing well rather than > tackling every problem in the Async space with one solution that has lots of > conventions. > > Also, Observables is firmly on the FP train, which I’m not. I prefer OOP > solutions to functional ones. > > For those not familiar with Observables and how complex/complete (depending > on your perspective) it is, take a look at this: > https://rxjs.dev/operator-decision-tree > > FWIW, I’ve entertained the idea of creating an Observable implementation for > Royale, but it was too much for me to undertake considering the chances of me > wanting to use it personally is slim. > >> On Oct 25, 2021, at 3:15 AM, Edward Stangler wrote: >> >> >> I assume you're describing Promises without async / await, below. >> >> How does your stuff compare to Observables? >> >> >> >> On 10/24/2021 5:28 AM, Harbs wrote: >>> 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> >>> <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