Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promise.retry 超时重新请求,并在重试一定次数依然失败时输出缓存内容 #142

Open
Sunny-117 opened this issue Nov 3, 2022 · 7 comments

Comments

@Sunny-117
Copy link
Owner

No description provided.

@ever-o
Copy link

ever-o commented Mar 29, 2023

Promise.retry = (callback, retryTime) => {
  // const curPromise = callback()
  return new Promise((resolve, reject) => {
    callback().then((value) => {
      resolve(value)
    }, (reason) => {
      if (!retryTime) reject(reason)
      else{
        Promise.retry(callback, --retryTime).then(resolve, reject)
      }
    })
  })
}
//let count = 0
// Promise.retry(() => {
//   console.log(++count)
//   return count === 3 ? Promise.resolve('success') : Promise.reject('failed')
// }, 3).then((value) => console.log(value), console.log)

@2239351258
Copy link

2239351258 commented Mar 30, 2023

/**
 * 超时重新请求,并在重试一定次数依然失败时输出缓存内容
 * @param {*} promiseFactory 一个返回 Promise 的函数,表示要执行的异步操作。
 * @param {*} maxRetries 一个整数,表示最大的重试次数。
 * @param {*} timeout 一个整数,表示每次重试的间隔时间(单位为毫秒)。
 * @param {*} cache 一个可选的参数,表示缓存的内容,如果重试多次依然失败,则会返回该缓存内容。
 * @returns promise
 */
function retry(promiseFactory, maxRetries, timeout, cache=null) {
  return new Promise((resolve, reject) => {
    let retries = 0;
    const executePromise = () => {
      promiseFactory()
        .then(resolve)
        .catch((error) => {
          retries++;
          if (retries >= maxRetries) {
            if (cache) {
              resolve(cache);
            } else {
              reject(error);
            }
          } else {
            setTimeout(executePromise, timeout);
          }
        });
    };
    executePromise();
  });
}
// ----------test----------
!(() => {
  const fetchData = () => {
    // 返回一个 Promise 对象,表示异步请求数据
    return fetch('http://example.com/data')
      .then((response) => response.json())
      .then((data) => {
        // 处理数据
        return data;
      });
  };

  retry(fetchData, 3, 10000, '缓存内容')
    .then((data) => {
      // 成功获取数据
      console.log(data);
    })
    .catch((error) => {
      // 请求失败或超时,并且重试多次依然失败
      console.error(error);
    });
})()

@JeromeD3
Copy link

JeromeD3 commented Apr 8, 2023

// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function (promiseFunc, num = 2) {
return promiseFunc().then(null, (e) => {
if (num > 0) {
num -= 1
console.log('重试')
return Promise.retry(promiseFunc, num)
}
return Promise.reject(e)
})
}
// test
function getProm() {
const n = Math.random()
return new Promise((resolve, reject) => {
setTimeout(() => (n > 0.9 ? resolve(n) : reject(n)), 1000)
})
}

Promise.retry(getProm)
.then((res) => {
console.log('成功', res)
})
.catch((err) => {
console.log('请求失败:', err)
})

@cscty
Copy link

cscty commented Jul 3, 2023

// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function (promiseFunc, num = 1) {
return promiseFunc().then(undefined, (err) => {
if (num > 0) {
num--;
return Promise.retry(promiseFunc, num);
}
return Promise.reject(err);
});
};
// test
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("开炮");
n > 0.9 ? resolve(n) : reject(n);
}, 1000);
});
}

        Promise.retry(getProm)
            .then((res) => {
                console.log("成功", res);
            })
            .catch((err) => {
                console.log("请求失败:", err);
            });

@IhInspiration
Copy link

Promise.retry = function(promiseCreator, limitTime, limitCount, cache) {
  return new Promise((resolve, reject) => {
    let retryCount = 1;
    
    const fn = () => {
      Promise.race([promiseCreator(), new Promise((innerResolve, innerReject) => {
        setTimeout(() => {
          innerReject('timeout');
        }, limitTime);
      })]).then((value) => {
        resolve(value)
      }, error => {
        console.log('开始尝试', retryCount)
        retryCount++;
        if (retryCount > limitCount) {
          if (cache) {
            resolve(cache);
          } else {
            reject(error)
          }
          return;
        }
        fn();
      })
    }

    fn();
  })
}

@whale2002
Copy link

Promise.retry = function (promiseFunc, num = 1) {
  return promiseFunc().then((res) => {
    return res
  }, (err) => {
    if (num > 0) {
      num--;
      return Promise.retry(promiseFunc, num);
    }
    return Promise.reject(err);
  });
};

function getProm() {
  const n = Math.random();
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(n)
      console.log("开炮");
      n > 0.9 ? resolve(n) : reject(n);
    }, 1000);
  });
}

Promise.retry(getProm)
  .then((res) => {
    console.log("成功", res);
  })
  .catch((err) => {
    console.log("请求失败:", err);
  });

@topulikeweb
Copy link

/**
 * Promise.retry当请求失败的时候,重新发起请求,直到请求成功
 * @param fn
 * @param time 重新请求的次数
 * @param delay 重启的延迟时间
 * @returns {Promise<unknown>}
 * @private
 */
Promise._retry = function (fn, time, delay) {
  let count = 0
  return new Promise((resolve, reject) => {
    function retry () {
      fn().then(res => {
        resolve(res)
      }, error => {
        count++
        if (count < time) {
          setTimeout(() => {
            console.log(`第${count}/${time}次请求`)
            // 如果失败,就重新请求
            retry()
          }, delay)
        } else {
          reject(new Error(`请求失败,以尝试${count}次`))
        }
      })
    }
    
    retry()
  })
}


// 示例:模拟一个可能失败的异步操作
const asyncOperation = () => {
  const random = Math.random();
  if (random < 0.3) {
    return Promise.resolve('Operation succeeded');
  } else {
    return Promise.reject(new Error('Operation failed'));
  }
};

// 使用 retryPromise 函数
Promise._retry(asyncOperation, 3, 2000)
.then((result) => {
  console.log(result);
})
.catch((error) => {
  console.error(error.message);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants