在承诺中包含一个反模式的承诺吗?

时间:2016-01-08 16:08:29

标签: javascript promise

我正在尝试使用Promise API编写用于重新连接到数据库的代码。

最终我最终做的是承诺在承诺中连接数据库,但我不确定这是否是最好的做事方式。我认为可能有一种方法可以使用原始的承诺来尝试连接数据库,但我无法弄明白。

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);

我认为没有setTimeout阻止就有可能,但我无法解决它。

1 个答案:

答案 0 :(得分:8)

这是一个更为通用的解决方案:

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));
}

如果Promise拒绝,该函数将采用一个返回promise和重试次数的函数,并重试该函数的次数retries

如果它结算,重试链就会停止。

在你的情况下:

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