Promise.retry 超时重新请求,并在重试一定次数依然失败时输出缓存内容
Sunny-117 opened this issue · comments
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)
/**
* 超时重新请求,并在重试一定次数依然失败时输出缓存内容
* @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);
});
})()
// 实现 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)
})
// 实现 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);
});
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();
})
}
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);
});
/**
* 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);
});