Is packaging a promise in the promise of an anti-pattern?

I tried to write code to reconnect to a database with a timeout using the Promise API.

What I ended up doing in the end was to promise to connect to the database as a promise, but I'm not sure if this is the best way to do something. I thought there might be a way to use the original promise while trying to connect to db, but I could not figure it out.

function connect(resolve) {
  console.log('Connecting to db...');
  MongoClient.connect(url, { promiseLibrary: Promise })
    .then((db) => resolve(db))
    .catch((err) => {
      console.log('db connection failed!:\n', err);
      if (retry++ < 3) {
        console.log('Trying again...');
        setTimeout(() => connect(resolve), 5000);
      } else {
        console.log('Retry limit reached!');
      }
    });
}

module.exports = new Promise(connect);

I think this is possible without a block setTimeout, but I could not get around it.

+5
source share
1 answer

Here is a slightly more general solution (tests for negative results):

function withRetry(asyncAction, retries) {
  if (retries <= 0) {
    // Promise.resolve to convert sync throws into rejections.
    return Promise.resolve().then(asyncAction); 
  }
  return Promise.resolve()
    .then(asyncAction)
    .catch(() => withRetry(asyncAction, retries - 1));
}

, , , , retries, .

, .

:

let connectionPromise = withRetry(connect, 3); // connect with 3 retries if fails.
+9

Source: https://habr.com/ru/post/1623450/


All Articles