2
cb219
3y

Rant/question:
httpDoSmth1().subscribe(x =>
...then(y =>
httpDoSmth2(x).subscribe(z =>
//do smth with z
return z
)
)
)
Isn't this (not my code) callback hell all over again? The 2. http call expects results from the 1. http call. I feel like this could be solved cleaner using async await/switchMap/etc. ... but not like this.

Comments
  • 1
    The underlying complexity will always be there, some patterns are just better at showing whats going on.

    But in the end its always up to the developers.

    No pattern will magically make bad code good and all can be abused to create an tangled mess ;)
  • 1
    If there's only a couple blocks like that then it's no big deal. If it's a large application where this goes on in dozens of files, you start seeing the benefits of some action/effect approach. Whatever makes it more readable and manageable; Good ol "it depends".
  • 1
    You can always return a new Promise.
  • 1
    Callbacks are problematic for two reasons. One is that asynchronous operations are complex and require a good state machine abstraction to ensure stability, the other is that the syntax is ugly.

    The latter can be solved with async await, in fact pretty much any idiot can wrap a callback API in a promise. The former can't be solved with tools. Not async await, not redux, not rxjs. If you can't design a good system all tools will fail. A good design takes a good designer, simple as that.
  • 0
    Okay I just noticed that this is Rx, I really don't think you should be using Rx here, because this is a pull system and because it's single-fire. Promises are your friend.
  • 1
    @ltlian dozen locations using various combinations
    I strongly prefer an async/await approach, splitting requests into distinct promises and awaiting these. Am I too perfectionist?
  • 1
    I guess you could use async/await to make the code look nicer, but it's still gonna be just as complex.

    For example

    fetch(uri, options).then(res => res.json()).then(result => { /* do stuff with result */ });

    becomes

    const response = await fetch(uri, options);

    const result = await response.json();

    /* do stuff with result */
  • 0
    @nitnip technically true but it matters. Async/await improves readability drastically and makes it easier to reason about the code.
  • 0
    The f is subscribe in this.

    Why not return the second promise in the then?
    Then you got it a bit more sequential (ly written. As stated, it's just sugar, it's the same anyways^^)

    Or use async, await
  • 1
    Call me a sadist but I prefer chaining promises over bracket city in async await syntax.
  • 0
    @nitwhiz @wackOverflow These are RxJS observables, there's no guarantee the callback is only gonna be called once. To me this is reason enough never to use them as the direct output of an API dealing with HTTP requests, but that's up to the request library developer.
  • 0
    @lbfalvy those http requests are used all over the place, nesting often included because of authentication. Subscriptions are said to cause memory leaks, but is that a concern?
  • 0
    @cb219 it's not even about memory leaks (I don't know about that), it's just not an expressive interface because your use case has a property - single value - that promises represent but observables don't.
Add Comment