title: Exponential backoff implementation with rxjs
body: <p>Angular 7 <a href="https://angular.io/guide/practical-observable-usage#exponential-backoff" rel="noreferrer">docs</a> provide this example of practical usage of <code>rxjs</code> <code>Observable</code>s in implementing an exponential backoff for an AJAX request:</p>
  
  <pre><code>import { pipe, range, timer, zip } from 'rxjs';
  import { ajax } from 'rxjs/ajax';
  import { retryWhen, map, mergeMap } from 'rxjs/operators';
  
  function backoff(maxTries, ms) {
   return pipe(
     retryWhen(attempts =&gt; range(1, maxTries)
       .pipe(
         zip(attempts, (i) =&gt; i),
         map(i =&gt; i * i),
         mergeMap(i =&gt;  timer(i * ms))
       )
     )
   );
  }
  
  ajax('/api/endpoint')
    .pipe(backoff(3, 250))
    .subscribe(data =&gt; handleData(data));
  
  function handleData(data) {
    // ...
  }
  </code></pre>
  
  <p>While I understand the concept of both Observables and backoff, I can’t quite figure out, how exactly <code>retryWhen</code> will calculate time intervals for resubscribing to the source <code>ajax</code>.</p>
  
  <p>Specifically, how do <a href="https://rxjs-dev.firebaseapp.com/api/operators/zip" rel="noreferrer"><code>zip</code></a>, <a href="https://rxjs-dev.firebaseapp.com/api/operators/map" rel="noreferrer"><code>map</code></a>, and <a href="https://rxjs-dev.firebaseapp.com/api/operators/mergeMap" rel="noreferrer"><code>mapMerge</code></a> work in this setup?</p>
  
  <p>And what’s going to be contained in the <code>attempts</code> object when it’s emitted into <code>retryWhen</code>?</p>
  
  <p>I went through their reference pages, but still can’t wrap my head around this.</p>