将承诺包装在承诺中是一种反模式

Is wrapping a promise in a promise an anti-pattern?

本文关键字:承诺 一种 模式 包装      更新时间:2023-09-26

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

我最终所做的是将连接到DB的承诺包装在一个承诺中,但我不确定这是否是最好的做法。我想可能有一种方法可以通过尝试连接到数据库来使用最初的承诺,但我想不通。

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块是可能的,但我无法解决它。

这里有一个更通用的解决方案(非阳性测试):

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.
相关文章: