首页 > 解决方案 > 记忆和重复的承诺

问题描述

我最近写了一个函数来重复调用一个函数(返回一个承诺),直到它成功。我的第一个想法是这样做:

//Takes a function that returns a Promise
static promiseKeepTrying(func) {

  const callFunc = () => {
    return func()
      .catch(() => {
        return this.promiseTimeout(5000)
          .then(() => callFunc())
      })
  }

  return callFunc()
}

static promiseTimeout(time) {
 return new Promise(resolve => setTimeout(resolve, time, time))
}

但我担心每个新调用都会创建一个与前一个调用关联的新 Promise,从而导致内存(缓慢)被消耗。那正确吗?

所以我选择了这个实现:

//Takes a function that returns a Promise
static promiseKeepTrying(func) {

  return new Promise((resolve) => {

    const callFunc = () => {
      func()
        .then(results => {
          resolve(results)
        })
        .catch(() => {
          setTimeout(callFunc, 5000)
        })
    }

    callFunc()
  })
}

我认为这个不会为每次重试消耗内存。那正确吗?

谢谢。

标签: javascriptpromise

解决方案


您的第二个实现确实避免了不断增加的承诺堆栈,因此将避免内存泄漏。

如果你想用 async/await 做类似的事情,你可以这样做:

async function promiseKeepTrying(func) {
  let result;
  let tries = 0;

  while (!result) {
    try {
      result = await func();
      return result;
    } catch(e) {
      tries++;
      // here, optionally you can throw after, say, 20 tries.
    }
  }
}

推荐阅读