retryable-promise-any

Retry a promise until the first one fulfills or all of them are rejected.

Stars
1

The problem:

As we are entering a time where our users expect our UI's and applications to responsible and fast, speed is becoming a foundation of a great UX. This requires us to re-think of how we interact with the server and how we ensure that critical information is not only retrieved, but retrieved in the minimal amount of time. So far, we have been used to retrying requests that fail, but how can we ensure that they are also delivered asap to our users and that a minimal amount of time is waster? Take for example, a search query. If that request takes 5 seconds to retrieve 200 results and ends up failing, we have wasted 5 seconds of our user's time. Retrying that same request again to receive only 100 results might reduce it's time to 2 seconds, but compounded we have wasted about 7 seconds of time, which is well enough for the user to go find a product they want on your competitor's website.

Solution

retryable-promise-any module helps you build a safe retry mechanism that retries requests before they fail. Given the example above, you can still send your request, but decide to set the timeout to 2 seconds and only fetch 100 results after that time. The main idea is that you will create a race between those two requests and ensure that whichever is the first to respond with success is the one that renders results for your users. This improves user experience by ensuring minimal time is wasted, even in case of errors and that any time spent retrying is not being compounded.

The module handles:

  • Ensuring request are raced to whichever is the first to respond (unlike Promise.all, a rejected promise doesn't short circuit the return)
  • Custom timeout strategies, specify almost any strategy you want or pick from a few hand built ones
  • Setting a max retryCount

Table of Contents

Installation

retryable-promise-any is published on npm's public registry, you can install it as a dependancy of your project with the following command.

npm install --save retryable-promise-any

Usage

import retryablePromiseAny from 'retryable-promise-any'

const search = retryablePromiseAny(
  (options) => search({hitsPerPage: 100 / options.currentRetryCount})
)
.then(renderResults)
.catch(handleAllFailures)

If you built something using retryable-promise-any that you want to show, feel free to send us a link and we'll include it to the documentation!

Contributing

This project is open to contributions, if you have a question, proposal or feedback please open a pull request or issue, we only ask you to be kind and respectful :)

Special thanks to Kent C. Dodds for building downshift (making that demo was much easier)

LICENSE

MIT