重复请求问题
使用Promise和AbortController来实现思路是:通过在会话缓存中存储和比较请求信息,来防止用户在短时间内重复提交相同的请求。
具体思路如下:
- 存储请求信息:每次请求时,将请求的相关信息(如URL、数据和时间)存储在会话缓存中,以便后续比较。
- 检查缓存:在处理新的请求时,首先从会话缓存中获取上一次请求的信息。
- 判断条件:通过比较当前请求和上一次请求的信息,判断是否为重复提交。具体判断条件包括:
- 请求的URL是否相同。
- 请求的数据是否相同。
- 当前请求时间与上次请求时间的差是否小于设定的间隔时间(例如1秒)。
- 处理重复提交:如果满足重复提交的条件,则阻止当前请求的处理,并返回一个错误信息,提示用户“数据正在处理,请勿重复提交”。
- 更新缓存:如果不满足重复提交的条件,则将当前请求的信息更新到会话缓存中,以便下次请求时进行比较。
// 假设我们有一个请求函数
function sendRequest(requestObj) {// 创建一个新的AbortController实例const controller = new AbortController();const signal = controller.signal;// 检查会话缓存中的请求信息const sessionObj = cache.session.getJSON('sessionObj');const interval = 1000; // 间隔时间(ms)if (sessionObj) {const s_url = sessionObj.url;const s_data = sessionObj.data;const s_time = sessionObj.time;// 检测重复请求if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {const message = '数据正在处理,请勿重复提交';console.warn(`[${s_url}]: ` + message);// 取消当前请求controller.abort();return Promise.reject(new Error(message));}}// 更新会话缓存cache.session.setJSON('sessionObj', requestObj);// 发起请求return fetch(requestObj.url, { method: 'POST', body: JSON.stringify(requestObj.data), signal }).then(response => {if (!response.ok) {throw new Error('请求失败');}return response.json();}).catch(error => {if (error.name === 'AbortError') {console.log('请求已取消');} else {console.error('请求错误:', error);}throw error;});
}// 使用如下。
const requestObj = {url: 'https://example.com/api',data: { key: 'value' },time: Date.now()
};sendRequest(requestObj).then(data => {console.log('请求成功:', data);}).catch(error => {console.error('请求失败:', error.message);});