Daily-Interview-Question
Daily-Interview-Question copied to clipboard
第 159 题:实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function (promiseFn, times = 3) {
return new Promise(async (resolve, reject) => {
while (times--) {
try {
var ret = await promiseFn();
resolve(ret);
break;
} catch (error) {
if (!times) reject(error);
}
}
});
};
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => n > 0.9 ? resolve(n) : reject(n), 1000);
});
}
Promise.retry(getProm);
写的不好,有好的写法大家可以指点一下,感谢
/*
实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
*/
// 同步获得Promise状态和值,这样写很low,要是更好的写法大家call我一下
async function checkPromise(getFlag) {
try {
let res = await getFlag();
return { flag: true, value: res };
} catch (e) {
return { flag: false, value: e };
}
}
async function retry(pro, count = 10) {
let result = {
flag: false,
value: null,
},
length = count;
while (count && !result.flag) {
console.log(`调用了${length - count + 1}次`);
result = await checkPromise(pro);
const { flag, value } = result;
if (!flag) {
count--;
}
}
return result.value;
}
Promise.retry = retry;
getFlag = function () {
return Math.random() > 0.5 ? Promise.resolve(1) : Promise.reject(-1);
};
Promise.retry(getFlag, 10)
.then((res) => {
console.log("成功结果", res);
})
.catch((e) => {
console.log("失败结果", e);
});
Promise.retry = function(fn, num){
return new Promise(function(resolve, reject){
while(num>0){
try{
const res = await fn
resolve(res)
num = 0
} catch(e){
if(!num) reject(e)
}
num --
}
})
}
function retry (fn, count = 10) {
return new Promise(async (resolve, reject) => {
while (count) {
try {
let res = await fn()
resolve(res)
return
} catch (e) {
if (!count) reject(e)
count--
}
}
})
}
/**
* 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
*/
Promise.retry = function(fn, limit) {
let i = 0
return new Promise((resolve, reject) => {
function retry() {
console.log('try!', i)
fn().then(res => {
resolve()
}).catch(err => {
i++
if(i > limit - 1) {
reject(err)
} else {
retry()
}
})
}
retry()
})
}
Promise.retry(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > .5 ? resolve() : reject()
}, 300);
})
}, 5).then(res => {
console.log('resolve')
}).catch(err => {
console.log('reject')
})
方法一:在 catch()
中再次执行函数
Promise.retry = function (fn, times) {
fn().then(console.log)
.catch(e => {
if (times > 0) {
console.log('try again...')
Promise.retry(fn, times - 1)
} else {
console.log('Error: No more times, now rejected.')
}
})
}
方法二:async
函数,结合 while
循环和 try...catch
Promise.retry = async function (fn, times) {
while (times > 0) {
try {
const res = await fn()
console.log(res)
return
} catch(e) {
console.log('try again...')
times--
}
}
console.log('Error: No more times, now rejected.')
}
测试:
const test = function () {
return new Promise((resolve, reject) => {
const num = Math.floor(Math.random() * 10)
if (num > 7) {
resolve(num)
} else {
reject(new Error(num))
}
})
}
Promise.retry(test, 5)
记得几年前面试一次面试时问过类似的问题,当时绞尽脑汁也没想出解决办法
/**
* promiseFn 返回promise 对象的函数
* max 最大重试次数
* interval 重试间隔时间
*/
Promise.retry = function (promiseFn, max=1, interval = 1000) {
function excuteFn(max) {
return promiseFn().then(res => {
return Promise.resolve(res);
}, err => {
if (max <= 1) {
return Promise.reject(err);
} else {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(excuteFn(--max));
}, interval);
})
}
})
}
return excuteFn(max)
}
// 测试用例
Promise.retry(ajax, 5, 1000)
.then(res => console.log('retry-res->', res))
.catch(err => console.log('retry-err->', err))
function ajax() {
const n = Math.random();
console.log('--->', n)
return new Promise((resolve, reject) => {
setTimeout(() => {
if (n > 0.9) {
resolve(`成功返回值--->${n}`)
} else {
reject(`失败返回值--->${n}`)
}
}, 3000);
})
}
// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function(fn, num){
return new Promise(async function(resolve, reject){
while(num>0){
try{
const res = await fn();
console.log('res: ', res);
resolve(res)
num = 0
} catch(e){
console.log('reject....');
if(num === 1) reject(e);
num--
}
}
})
}
const test = () => {
return new Promise((resolve, reject) => {
const num = Math.floor(Math.random() * 10);
if (num > 5) {
resolve(num);
} else {
reject(`num 小于等于8`);
}
})
}
Promise
.retry(test, 5)
.then(res => {
console.log('result: ', res);
})
.catch(err => {
console.log('err: ', err);
})
更加具有抽象形式的retry,尝试反复执行一个方法,方法内部可以是异步请求,或者其他需要retry的动作,如请求动画等等。所以,我给出的retry函数的ts形式是这样的。
function retry(times:number,fn:Function){
let counter = 0,maxTimes = times +1;
let resp , err;
while(counter < maxTimes){
err = undefined;
try{
resp = fn();
}catch(error){
err = error;
}
if(err === undefined){
break;
}
}
if(err){
throw err;
}
return resp;
}
retry(3,()=>{
console.log("test");
throw new Error("retry error")
return {}
})
// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
// 这道题刚开始做的时候,写漏了一个条件:超过一定次数才是真正的reject。
// 这里用for + break 去做次数限制
Promise.retry = function(fn, max = 5) {
return new Promise(async (resolve, reject) => {
let res = null
for (let i in [...Array(max)]) {
try {
console.log('try: ', i)
res = await fn()
break
} catch(e) {
if(+i === (max - 1)) {
reject(e)
return
}
}
}
resolve(res)
})
}
function fn () {
let n = Math.random()
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Current random value: ', n)
n > 0.75 ? resolve(n) : reject(n)
}, 2000)
})
}
Promise.retry(fn, 10)
.then(res => console.log('Resolve: ', res))
.catch(res => console.log('Reject: ', res))
感觉题目可以清晰一些,指定retry的入参是啥
Promise.retry = function (fn, times) {
return new Promise((rs, rj) => {
return fn().then((res) => {
rs(res)
}).catch((err) => {
if (--times >= 0) {
return Promise.retry(fn, times)
} else {
rj(err)
}
})
})
}
为啥感觉你们写的怎么这么复杂 。。。
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);
});
};
再简化一下
Promise.retry = function (promiseFunc, num = 2) {
return promiseFunc().then(null, (e) => num > 0 ? Promise.retry(promiseFunc, num - 1) : Promise.reject(e));
};
感觉题目可以清晰一些,指定retry的入参是啥
Promise.retry = function (fn, times) { return new Promise((rs, rj) => { return fn().then((res) => { rs(res) }).catch((err) => { if (--times >= 0) { return Promise.retry(fn, times) } else { rj(err) } }) }) }
我就想问这一句:return fn().then((res) => rs(res)); 题目没说fn函数返回的一定是Promise吧?普通函数调用then不就报错了
(function () {
function retry(func, max = 2, err) {
return new Promise((resolve, reject) => {
return func()
.then(resolve)
.catch(err => {
console.log('retry', max);
if (max <= 0) {
return reject(err)
}
return retry(func, max - 1);
})
.catch(reject);
})
}
retry(() => Promise.resolve(1))
.then(res => {
console.log('成功', 1)
})
.catch(err => {
console.log('fail');
})
retry(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(111);
}, 3000);
})
})
.then(res => {
console.log('成功', res)
})
.catch(err => {
console.log('fail', err);
})
})();
if (Promise) {
Promise.retry = function (fn, time) {
return new Promise((resolve, reject) => {
const retry = (i) => {
return Promise.resolve(fn()).then(res => {
resolve(res);
}).catch(err => {
if (i <= time) {
return retry(++i);
} else {
reject(err);
}
})
}
return retry(0);
});
}
}
Promise.retry(function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('resolve...');
reject('reject...');
}, 300);
});
}, 3).then(res => {
console.log('res: ', res);
}).catch(err => {
console.log('err:', err);
});
Promise.retry = function (task, retryTimes) {
if(retryTimes <= 0) {
new Error('wrong params that retry times')
}
return new Promise((resolve, reject) => {
function runTask() {
if(retryTimes === 0) {
reject(new Error('have no retry times'))
return
}
task()
.then((v) => {
resolve(`success ${v}`);
})
.catch(() => {
retryTimes--
runTask()
});
}
runTask();
});
};
Promise.retry = function (getPromise, num) {
if (num === 1) return getPromise()
return getPromise().then(res => res, () => Promise.retry(getPromise, --num))
}
Promise.retry = function(fn,max = 3){
let count = 0;
return new Promise((resolve,reject)=>{
function handler(){
fn().then((res)=>{
resolve(res)
}).catch((err)=>{
count++;
if(count >= max){
reject(err)
}else{
handler()
}
})
}
handler()
})
}
Promise.retry = (times = 10, fn) =>
// eslint-disable-next-line no-async-promise-executor
new Promise(async (resolve, reject) => {
while (times > 0) {
// eslint-disable-next-line no-param-reassign
times -= 1;
try {
// eslint-disable-next-line no-await-in-loop
const ret = await fn();
return resolve(ret);
} catch (err) {
if (times <= 0) {
return reject(err);
}
}
}
});
// Test case
const test = () => new Promise((resolve, reject) => {
if (Math.random() < 0.2) {
resolve('good luck');
} else {
reject(new Error('bad luck'));
}
});
Promise.retry(2, test).then((ret) => {
console.log(ret);
}).catch((err) => {
console.log(err);
});
async function retry<T>(n: number, action: () => Promise<T>): Promise<T> {
if (n <= 0) throw "Try all"
try {
let result = await action()
return result
} catch(_) {
return retry(n - 1, action)
}
}
比如重试 5 次
let time = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("error");
}, 1000);
});
};
async function f(retry = 5) {
while (retry !== 0) {
try {
const result = await time();
return result;
} catch (e) {
if (--retry === 0) {
throw e
}
}
}
}
//函数
Promise.retry = function (promise, num) {
console.log(num);
return promise().then(res => res, function () {
return num == 1 ? promise() : Promise.retry(promise, --num)
});
}
//箭头函数
Promise.retry = (promise, num) =>
promise().then(res => res, () =>
num == 1 ? promise() : Promise.retry(promise, --num)
);
//test
Promise.retry(Promise.resolve.bind(Promise, "reslove"), 5);
Promise.retry(Promise.reject.bind(Promise, "reject"), 5);
实现
对于常见的应用场景,至少应该满足重试次数和每次重试的间隔可配置,失败后立即重试意义并不大。
/**
* Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 rejec
* @param {(resolve, reject) => any} fn 执行函数
* @param {number} max 最大尝试次数
* @param {number} interval 尝试间隔
* @param {number} count 函数内部统计
*/
export function retry(fn, max = 1, interval = 1000, count = 0) {
--max
++count
return new Promise((resolve, reject) => {
const wrapResolve = (res) => {
resolve(res)
}
const wrapReject = (error) => {
if (max >= 0) {
setTimeout(() => {
console.log(`第${count}次重试`)
resolve(retry(fn, max, interval, count))
}, interval)
} else {
reject(error)
}
}
fn(wrapResolve, wrapReject)
})
}
Promise.retry = retry
测试
// 单纯的失败场景
function testFail(_, reject) {
reject(new Error('error'))
}
Promise.retry(testFail, 10)
.catch(error => conso.log(error)
// 单纯的成功场景
function testSuccess(resolve) {
resolve('success')
}
Promise.retry(testSuccess, 10)
.then(res => console.log(res))
// 重试成功的场景
let count = 0
function testRetrySuccess(resolve, reject) {
++count
count > 3 ? resolve('success') : reject(new Error('error'))
}
Promise.retry(testRetrySuccess, 10)
.then(res => console.log(res))
Promise.retry = function(fn,time=5){
let flag = false
return new Promise(async (resolve,reject)=>{
while(time>0 && !flag){
try{
const res = await fn()
resolve(res)
flag = true
}catch(e){
if(time<=0){
reject(e)
}
time--
}
}
})
}
实现
含最大次数 & 延迟执行
Promise.retry = (fn, options = {}) => {
const { max = 3, delay = 0 } = options
let curMax = max
const delayExec = () => delay && new Promise(resolve => setTimeout(resolve, delay))
return new Promise(async (resolve, reject) => {
do {
try {
const res = await fn()
resolve(res)
return
} catch (error) {
await delayExec()
curMax--
console.warn(`剩余次数${curMax}`)
if (!curMax) reject(error)
}
} while (curMax > 0)
})
}
测试
const resolveData = () => {
return new Promise((resolve, reject) => {
setTimeout(
() => (Math.random() > 0.5 ? resolve('成功') : reject(new Error('失败')))
, 1000,
)
})
}
;(async () => {
try {
const res = await Promise.retry(resolveData, { delay: 1000 })
console.warn('result', res)
} catch (error) {
console.warn(error)
}
})()
Promise.retry = function(fun,max=2){
return fun().then(Promise.resolve(),(err)=>{
if(!max){
return Promise.reject(err);
}else{
return Promise.retry(fun,--max);
}
})
}
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => n > 0.5 ? resolve(n) : reject(n));
}, 1000);
}
Promise.retry(getProm).then((a)=>{
console.log(a);
});
Promise.retry=function(fn,number=3){
return function(...args){
let time=0;
var next=function(resolve,reject){
fn(...args)
.then(function(...res){
console.log(res)
resolve(...res)
})
.catch(function(...error){
if(time===number){
reject(...error);
time=0;
}else{
time++;
next(resolve,reject)
}
})
}
return new Promise(function(resolve,reject){
next(resolve,reject)
})
}
}
function testSuccess(params) {
return new Promise(function(resolve,reject) {
resolve(params)
})
}
function tetestError(params) {
return new Promise(function(resolve,reject) {
reject(params)
})
}
let success=Promise.retry(testSuccess);
success('我是成功')
.then(function(params) {
console.log(params)
})
.catch(function (err) {
console.log(err)
})
let error=Promise.retry(tetestError);
error('我是成功')
.then(function(params) {
console.log(params)
})
.catch(function (err) {
console.log(err)
})
Promise.prototype.retry = function(fn) {
var resolve;
var reject;
var p = new Promise(function(res, rej) {
resolve = res;
reject = rej;
});
var retryReject = function(err) {
fn(resolve, reject)
}
fn(resolve, retryReject);
return p;
}
Promise.prototype.retry((resolve, reject) => {
console.log('尝试')
reject('err')
}).then(res => {console.log(res)}, rej => {
console.log(rej);
})
Promise.retry = function(fn, times) {
let n = 0
return new Promise((resolve, reject) => {
next(resolve, reject)
})
function next(resolve, reject) {
fn().then(resolve).catch(e => {
n++
n === times ? reject(e) : next(resolve, reject)
})
}
}
上面大部分有有个问题,不一定try-catch报错了才reject,得到不符合预期的结果也是reject的
Promise.retry = (promise, times) => {
return new Promise((resolve, reject) => {
const fn = async (promise, num = 0) => {
try {
const res = await promise;
resolve(res);
} catch (error) {
if (num >= times) {
reject(error);
} else {
fn(promise, num + 1);
}
}
};
fn(promise);
});
};
Promise.retry = async (fn, times) => {
while (true) {
try {
return await fn()
} catch (e) {
if (times-- === 0) {
throw e
}
}
}
}
// async/await
Promise.retry = (asyncFn, times) => {
// 把重试函数包装成 Promise
let retPromsie = () => Promise.resolve().then(() => {
try {
return asyncFn()
} catch(e) {
throw Error(e)
}
})
return new Promise((resolve, reject) => {
let i=times
const retry = async () => {
if(i==0) return
try {
let ret = await retPromsie()
ret!=undefined && resolve(ret)
} catch (e) {
i==1 && reject(e)
}
i--
retry()
}
retry()
})
}
// const fn = () => a+b // ReferenceError: a is not defined
const fn = (a, b) => a+b // 3
Promise.retry(fn.bind(null, 1,2), 3).then(console.log, console.log)
// Promise
Promise.retry = (asyncFn, times) => {
// 把重试函数包装成 Promise
let retPromsie = () => Promise.resolve().then(() => {
try {
return asyncFn()
} catch(e) {
throw Error(e)
}
})
const promiseFn = asyncFn instanceof Promise ? asyncFn : retPromsie
if(times==1) return Promise.reject(promiseFn())
return Promise.resolve(promiseFn()).then(null, () => Promise.retry(promiseFn, times-1))
}
// const fn = () => a+b // ReferenceError: a is not defined
const fn = (a, b) => a+b // 3
Promise.retry(fn.bind(null, 1,2), 3).then(console.log, console.log)
Promise.retry = function (fn, max = 3) {
let p = new Promise(fn);
while (max) {
p = p.catch(() => {
console.log("失败");
return new Promise(fn);
});
max -= 1;
}
return p;
};
// 测试 执行一个递增的i;i>1时会成功
let i = 0;
Promise.retry((resolve, reject) => {
setTimeout(() => {
if (i > 1) resolve("我成功了");
i += 1;
reject();
}, 1000);
}).then(
(res) => {
console.log("res", res);
},
(err) => {
console.log("err", err);
}
);
var num = 0
var fn = () => {
num++
return new Promise((resolve, reject) => {
if (num == 5) { // 修改这个数字可以模拟失败多少次
resolve('成功')
} else {
reject('失败')
}
})
}
Promise.retry = function (promiseFn, times, interval) {
return new Promise((resolve, reject) => {
let recur = () => {
promiseFn().then((data) => {
resolve(data)
}).catch(e => {
times--
console.log('失败了一次');
if (times === 0) {
reject(e)
} else {
setTimeout(() => {
recur()
}, interval);
}
})
}
recur()
})
}
Promise.retry(fn, 3, 2000).then((data) => {
console.log(data);
},(e) => {
console.log(e);
})
function retry (fn, count = 10) { return new Promise(async (resolve, reject) => { while (count) { try { let res = await fn() resolve(res) return } catch (e) { if (!count) reject(e) count-- } } }) }
应该先count--,不然永远也进不了catch那步啊
(() => {
Promise._retry = function (fn, count) {
return new Promise(async (resolve, reject) => {
while (count) {
try {
const res = await fn()
resolve(res)
return
} catch (err) {
count--;
if(count) console.log('重试中,剩余次数:' + count); // 用例
if (!count) reject(err)
}
}
});
}
// 用例
let p = function () {
return new Promise((resolve, reject) => {
reject('没有了,没有总冠军了o(╯□╰)o');
});
};
Promise._retry(p,10).then(res=>console.log(res)).catch(e=>console.log(e))
})();
弱弱的发一个, 思路: fn 属于 Promise while 需要 await 阻塞 递归 可以直接回调 异步
Promise.retry = function (fn, count) {
return new Promise((resolve, reject) => {
console.log(count)
const pro = fn();
if (!(pro instanceof Promise)) {
i = 0;
throw new Error('不是 Promise');
}
pro.then((res) => {
resolve(res)
}).catch(e => {
if (count <= 0) {
return reject(e);
}
Promise.retry(fn, count--);
})
})
}
promise里用try cath的你们不觉得诡异的么🙄,好好的在其promise上链式catch不好吗的。。。
Promise.retry = function (promiseFn, limitTime = 3) {
function executeFn(count = 1) {
console.count('执行了');
return promiseFn().then(res => res).catch(err => {
if (count < limitTime) {
return executeFn(count + 1);
} else {
return Promise.reject(err);
}
});
}
return executeFn();
};
// 测试用例
function test(time = 5) {
let count = 0;
function res() {
count++;
if (count < time) {
return Promise.reject('no');
} else {
return Promise.resolve('yes'); //默认第time次执行才成功
}
}
return res;
}
const testFn = test();
const restryTime = 3; //重试次数
// const restryTime = 5;
Promise.retry(testFn, restryTime).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
实现
Promise.retry = (fn = () => {}, times = 0) =>
new Promise(async (resolve, reject) => {
let count = -1;
retryTask:
while (count < times) {
try {
(count !== -1) && console.log(`retry No.${count + 1}`);
const res = await fn();
resolve(res);
break retryTask;
} catch (err) {
(++count === times) && reject(err);
}
}
});
测试
// test function
const task = () => {
return new Promise((resolve, reject) => {
console.log('task run');
setTimeout(() => {
reject(new Error());
}, 1000);
})
};
// case1
Promise.retry(task).then(res => {
console.log('Task1 resolved');
}).catch(err => {
console.error('Task1 rejected, error is:', err);
})
// case2
Promise.retry(task, 1).then(res => {
console.log('Task2 resolved');
}).catch(err => {
console.error('Task2 rejected, error is:', err);
})
// case3
Promise.retry(task, 6).then(res => {
console.log('Task3 resolved');
}).catch(err => {
console.error('Task3 rejected, error is:', err);
})
var count = 1;
function ajax() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (count > 4) {
resolve('success')
} else {
count++;
reject('error')
}
}, 1000)
})
}
Promise.retry = function (promise, num) {
let c = 1;
return new Promise((resolve, reject) => {
function loop() {
promise().then(res => {
resolve(res)
}).catch(err => {
if (c > num) {
reject(err)
} else {
c++
loop();
}
})
}
loop()
})
}
Promise.retry(ajax, 8).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
function retry2(fn, times) {
times--;
return new Promise((resolve, reject) => {
resolve(fn());
})
.then((res) => {
return times;
})
.catch((err) => {
if (times > 0) {
return retry2(fn, times);
}
return Promise.reject(err);
});
}
/**
*
* @param {function} fn 请求后端接口的方法
* @param {number} times 重试次数
* @param {function} retryCondition 触发重试的条件
* @returns {function}
*/
function withRetry(fn,times=3,retryCondition){
return function(){
const args = Array.prototype.slice.call(arguments);
return new Promise((resolve,reject) => {
doRequest(resolve,reject);
function doRequest(resolve,reject){
fn.apply(null,args).then((res) => {
if(!retryCondition(res)) return resolve(res);
if(times==0) return reject(res);
times--;
doRequest(resolve,reject);
}).catch(e=>{
if(times==0) return reject(e);
times--;
doRequest(resolve,reject);
})
}
})
}
}
- 如果可以用 async await 的话,那么可以用 while 循环,通过同步的语法实现
- 如果不能用 async await 的话,那么可以用 Promise 递归调用的方法实现
如果要求两次请求间隔一段时间,用 promise 会更方便
在外层使用 async
Promise.retry = async function (fn, times = 3) {
while (true) {
console.log(times);
times--;
try {
const res = await fn();
return res;
} catch (error) {
if (times === 0) throw error;
}
}
};
在内层使用 async
Promise.retry = function (promiseFn, times = 3) {
return new Promise(async (resolve, reject) => {
while (true) {
console.log(times);
times--;
try {
var ret = await promiseFn();
resolve(ret);
break;
} catch (error) {
if (times === 0) {
reject(error);
break;
}
}
}
});
};
使用 promise
Promise.retry = function (fn, times = 3) {
return new Promise(function (resolve, reject) {
function retry() {
console.log(times);
times--;
fn()
.then(resolve)
.catch((error) => {
if (times === 0) {
reject(error);
} else {
retry();
}
});
}
retry();
});
};
Promise.retry = function (callback) {
return new this(callback)
.then((res) => {
return res;
})
.catch(() => {
return new this(callback);
});
};
Promise.retry((resolve, reject) => {
setTimeout(() => {
const nub = Math.random();
console.log(nub);
nub > 0.5 ? resolve(nub) : reject(nub);
}, 1000);
}).then(
(res) => {
console.log("res", res);
},
(err) => {
throw err;
},
Promise.retry = function (callback, count = 1) {
const retryHandle = () => {
return new this(callback)
.then((res) => {
return res;
})
.catch((error) => {
count--;
console.log(count);
if (count <= 0) {
return this.reject(error);
} else {
return retryHandle();
}
});
};
return retryHandle();
};
Promise.retry((resolve, reject) => {
setTimeout(() => {
const nub = Math.random();
console.log(nub);
nub > 0.5 ? resolve(nub) : reject(nub);
}, 1000);
}, 5).then(
(res) => {
console.log("res", res);
},
(err) => {
throw err;
},
);
使用生成器实现
Promise.retry = function (promiseFunc, times = 3) {
return new Promise((resolve, reject) => {
function * gen () {
let ret = yield promiseFunc()
while (times --) {
ret = yield promiseFunc()
}
return ret
}
const iterator = gen()
const onFulfilled = (res) => resolve(res)
const onRejected = (err) => {
let ret = iterator.next()
if (ret.done) {
return reject(err)
}
next(ret)
}
const next = (ret) => ret.value.then(onFulfilled, onRejected)
next(iterator.next())
})
}
Promise.retry = function (promiseFun, times = 5) {
return new Promise((resolve, reject) => {
const getResult = () => {
times --;
promiseFun().then(res => {
console.log(res)
resolve(res);
}).catch(error => {
console.log(error)
if (times <= 0) {
reject(error);
} else {
getResult();
}
});
}
getResult();
})
}
Promise.retry(async () => {
const randomNum = Math.random() - 0.9;
if (randomNum > 0) {
return `success: ${randomNum}`;
} else {
return Promise.reject(`fail: ${randomNum}`)
}
})
直接递归处理
Promise.retry = function (promiseFn, times = 3) { return new Promise((resolve,reject)=> promiseFn().then(res=>resolve(res)).catch(err=>times ? Promise.retry(promiseFn, times-1) : reject(err))) }
Solution using recursion
Promise.retry = (func, times = 3) => {
return new Promise(async (resolve, reject) => {
try {
await func();
resolve();
} catch(e) {
times--;
if (!times) reject();
else Promise.retry(func, times);
}
})
}
const execute = (str) => {
console.log(str);
return new Promise((resolve, reject) => {
setTimeout(() => Math.random() > 0.5 ? resolve() : reject(), 500);
})
}
Promise.retry(execute.bind(null, 'execute'));
你的邮件我已收到,我会马上查看! —————————————————————— 现在的追逐梦想是为了日后能拥有美好的“那些年”!
Promise.retry = function (promiseFn, times = 3) {
//success resolve, else try times
let count = times;
let promise = promiseFn;
return new Promise((resolve, reject) => {
_retry(resolve, reject);
function _retry(resolve, reject) {
promise().then(
(res) => resolve(res),
(err) => {
if (count == 0) return;
count--;
console.log('重新尝试连接');
_retry(resolve, reject);
}
);
}
});
};
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) =>
setTimeout(() => (n > 0.9 ? resolve(n) : reject(n)), 1000)
);
}
try {
Promise.retry(getProm).then(
(res) => console.log(res),
(err) => console.log(err)
);
} catch (e) {
console.log(e);
}
Promise.retry = (promiseFn, tries = 3) => {
return new Promise(async (resolve, reject) => {
while (tries > 0) {
tries--;
try {
const result = await promiseFn();
resolve(result);
break;
} catch (error) {
if (tries === 0) reject(error);
}
}
});
};
const over70 = () => {
const n = Math.floor(Math.random() * 100);
return new Promise((resolve, reject) => {
setTimeout(() => (n > 70 ? resolve(n) : reject(n)), 10);
});
};
Promise.retry(over70)
.then((result) => console.log('then', result))
.catch((result) => console.log('catch', result));
你的邮件我已收到,我会马上查看! —————————————————————— 现在的追逐梦想是为了日后能拥有美好的“那些年”!
function retry(fn, options = {}) {
let { times = 3 } = options;
const { delay = 1000 } = options;
return new Promise((resolve, reject) => {
const tryOnce = () => {
fn()
.then(resolve)
.catch((err) => {
times -= 1;
if (times > 0) {
console.log('retry', times);
setTimeout(() => {
tryOnce();
}, delay);
return;
}
reject(err);
});
};
return tryOnce();
});
}
你的邮件我已收到,我会马上查看! —————————————————————— 现在的追逐梦想是为了日后能拥有美好的“那些年”!
Promise.retry = function (fn, count = 3) {
return new Promise((rs, rj) => {
const p = function () {
count--;
return fn().then(r => {
rs(r);
}).catch((e) => {
if (!count) {
rj(e);
} else {
p();
}
});
}
p();
});
}
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) => {
console.count('getProm');
setTimeout(() => n > 0.9 ? resolve(n) : reject(n), 1000);
});
}
Promise.retry(getProm).then(r => {
console.log('ok')
}).catch(e => {
console.log('fail')
});