Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS Approach leads to Callback Hell

I would like to use ReactiveJS Observable method for the below use case.

IF MAIN_CACHE EXIST
  RETURN OUTPUT
ELSE IF DB CONNECTION EXIST
  CACHE MAIN_CACHE (1 Hour)
  CACHE FALLBACK_CACHE (3 Days)
  RETURN OUTPUT
ELSE IF FALLBACK_CACHE EXIST
  RETURN OUTPUT

I got the expected output but i feel this leads to Callback Hell and I think, still its not a good approach and i'm missing something in ReactiveJS Observable key benefits.

Below is my code and the whole code is in JS Bin Link

mainCache.subscribe(function (response) {
  console.log(response);
}, function (error) {
    dbData.subscribe(function (response) {
      console.log(response);
    }, function (error) {
        console.log('DB CAL Log info', error);
        fallbackCache.subscribe(function (response) {
          console.log('FALLBACK CACHE SERVED');
          console.log(response);
        }, function (error) {
          console.log('DB CAL Log error', error);
        });
    });
});

Any lights. much appreciated with working example.

like image 979
Alamelu Venkat Avatar asked Jul 11 '26 18:07

Alamelu Venkat


1 Answers

Your implementation indeed is callback hell. You can avoid it by composing your observables with the available rxjs operators, and subscribe at the end when you want to receive the data and have no more transformation. You can have a look at How to do the chain sequence in rxjs and Why we need to use flatMap?, to see how to chain operators, and use only one subscribe at the end of the chaining.

Here your chaining comes from catching errors, so like promises, the best practice is to catch early the errors, as you do, and for that you can use the catch operator`.

mainCache
  .do(console.log.bind(console))
  .catch(err => dbData.catch(err => {
     console.log('DB CAL Log info', error);
     return fallbackCache.do(response => {
          console.log('FALLBACK CACHE SERVED');
          console.log(response);       
     }).catch(console.log.bind(console, `DB CAL Log error`))
   }))

This is only tangential to your use case, but for information, I include also this link, which deals with retrial in case of miss (for example from dbData): retryWhen with backoff

like image 146
user3743222 Avatar answered Jul 14 '26 09:07

user3743222



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!