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