Alamelu Venkat
Alamelu Venkat

Reputation: 471

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.

Upvotes: 3

Views: 727

Answers (1)

user3743222
user3743222

Reputation: 18665

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

Upvotes: 4

Related Questions