js 使用 Promise 实现 Fetch 请求超时重试 All In One
js 使用 Promise 实现 Fetch 请求超时重试 All In One
Using Promises to implement Fetch request timeout retry
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2020-11-20
* @modified 2022-03-20
*
* @description js 使用 Promise 实现 Fetch 请求超时重试
* @description
* @difficulty Medium
* @complexity O(n)
* @time O(n)
* @augments
* @example
* @link https://www.cnblogs.com/xgqfrms/p/16038719.html
* @link https://www.cnblogs.com/xgqfrms/p/14016391.html
* @solutions
*
* @best_solutions
*
*/
const log = console.log;
function maxRequest(url = ``, times = 3) {
// 1. 闭包,保存私有属性
function autoRetry (url, times) {
console.log('times = ', times);
times--;
// 2. fetch 本身返回值就是 Promise,不需要再次使用 Promise 包裹
return fetch(url).then(value => {
if(value.status === 200) {
console.log(`? OK`, value);
// 3. 手动返回 Promise 的 value, 没有返回值 默认返回 undefined
return value;
} else {
throw new Error(`? http code error: ${value.status }`);
}
}).catch((err) => {
console.log(`? Error`, err);
if (times < 1) {
// 4. 方便后续的 thenable 处理 error
throw new Error('?? over max request times!');
} else {
// 5. 返回递归方法
return autoRetry(url, times);
}
});
}
// 6. 返回一个 Promise 的结果 (成功 Promise 或失败 Promise)
return autoRetry(url, times);
}
// error test case
maxRequest(`https://cdn.xgqfrms.xyz/json/badges.js`)
.then(res => res.json())
.then(json=> console.log('json =', json))
.catch(err => console.error(`err =`, err))
.finally(() => {
console.log('?? whatever close loading...');
});
// sucess test case
maxRequest(`https://cdn.xgqfrms.xyz/json/badges.json`)
.then(res => res.json())
.then(json=> console.log('json =', json))
.catch(err => console.error(`err =`, err))
.finally(() => {
console.log('?? whatever close loading...');
});
Promise then & return value
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#return_value
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
Promise constructor antipattern
Promise 构造函数 反模式
function autoRetry (url, times) {
return new Promise((resolve, reject) => {
// fetch(url).then...
});
}
function autoRetry (url, times) {
return new Promise((resolve, reject) => {
// Promise.resolve(fetch(url).then...)
});
}
bad demos
function maxRequest(url = ``, times = 3) {
// 闭包
function autoRetry (url, times) {
console.log('times = ', times);
times--;
return new Promise((resolve, reject) => {
Promise.resolve(fetch(url)).then(value => {
if(value.status === 200) {
console.log(`? OK`, value);
resolve(value);
} else {
throw new Error(`? http code error: ${value.status }`);
}
}).catch((err) => {
console.log(`? Error`, err);
if (times < 1) {
reject('?? over max request times!');
} else {
autoRetry(url, times);
}
});
});
}
return autoRetry(url, times);
}
function maxRequest(url = ``, times = 3) {
// 闭包
function autoRetry (url, times) {
console.log('times = ', times);
times--;
return new Promise((resolve, reject) => {
Promise.resolve(fetch(url).then(value => {
if(value.status === 200) {
console.log(`? OK`, value);
resolve(value);
} else {
throw new Error(`? http code error: ${value.status }`);
}
}).catch((err) => {
console.log(`? Error`, err);
if (times < 1) {
reject('?? over max request times!');
} else {
autoRetry(url, times);
}
}));
});
}
return autoRetry(url, times);
}
https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it
fix: Uncaught (in promise) ?
https://stackoverflow.com/questions/71562261/error-message-uncaught-in-promise-but-i-cant-find-whats-wrong-with-that-af#
refs
https://javascript.info/async
?xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有??xgqfrms, 禁止转载 ???,侵权必究??!