-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
第 159 题:实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject #387
Comments
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 = 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')
}) |
方法一:在 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.')
}
})
} 方法二: 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) |
|
// 实现 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 {}
}) |
|
感觉题目可以清晰一些,指定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));
}; |
我就想问这一句:return fn().then((res) => rs(res)); |
(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 次
|
//函数
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 = (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);
})
}
})
}
} |
如果要求两次请求间隔一段时间,用 promise 会更方便 在外层使用 asyncPromise.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;
}
}
}; 在内层使用 asyncPromise.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;
}
}
}
});
}; 使用 promisePromise.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}`)
}
}) |
|
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 = (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')
}); |
利用 Promise 的链式特性,1行代码就能解决,无需循环、async: Promise.retry = (fn, times = 0) => {
return fn().catch(() => times > 0 ? Promise.retry(fn, times - 1) : Promise.reject())
} 调用测试: function getRandom() {
const n = Math.random()
console.log(n);
return new Promise((resolve, reject) => {
setTimeout(() => (n > 0.9 ? resolve(n) : reject(n)), 1000)
})
}
Promise.retry(getRandom, 2)
.then(() => console.log('done'))
.catch(() => console.log('rejected')) 带注释版: Promise.retry = (fn, times = 0) => {
return fn().catch((err) => {
// 继续尝试
if (times > 0) return Promise.retry(fn, times - 1)
// 抛出异常
return Promise.reject(err)
})
} |
function fetchTest(params = {}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
let n = (Math.random() * 10 + 1) | 0;
console.log('n', n);
console.log('params', params);
if (n > 5) {
reject('error' + n);
}
resolve(n);
}, 1000);
});
}
Promise.retry = function(fn, times = 3) {
return new Promise((resolve, reject) => {
function attempt() {
fn()
.then(resolve)
.catch(err => {
if (times === 1) {
reject(err);
} else {
times--;
attempt();
}
});
}
attempt();
});
};
Promise.retry(fetchTest.bind(null, { a: 1, b: 2 }))
.then(res => {
console.log('res', res);
})
.catch(err => {
console.log('err', err);
}); |
你的邮件我已收到,我会马上查看!
——————————————————————
现在的追逐梦想是为了日后能拥有美好的“那些年”!
|
async function retry(fn, num = 5) {
try {
const res = await fn();
console.log("resolve", res);
} catch (e) {
num-- && retry(fn, num);
}
}
Promise.retry = retry; |
你的邮件我已收到,我会马上查看!
——————————————————————
现在的追逐梦想是为了日后能拥有美好的“那些年”!
|
Promise.retry = (promiseFunc, retryCount = 3) => {
let count = retryCount;
const run = async (resolve, reject) => {
count -= 1;
try {
const result = await promiseFunc();
resolve(result);
} catch (error) {
if (count === 0) {
return reject(error);
}
run(resolve, reject);
}
};
return new Promise(run);
}; |
你的邮件我已收到,我会马上查看!
——————————————————————
现在的追逐梦想是为了日后能拥有美好的“那些年”!
|
|
你的邮件我已收到,我会马上查看!
——————————————————————
现在的追逐梦想是为了日后能拥有美好的“那些年”!
|
No description provided.
The text was updated successfully, but these errors were encountered: