为了实现一个React页面使用定时器调用一组多个接口,并在任意一个接口请求返回令牌失效时清除定时器且不再触发这一组请求,可以遵循以下步骤:
1. 定义API调用函数:创建一个函数来处理一组API调用。每个API调用都应该检查响应状态以确定令牌是否有效。
2. 设置定时器:使用useEffect钩子和setInterval来设置定时器,该定时器会定期调用上述API调用函数。
3. 错误处理:在API调用中加入错误处理逻辑,特别是针对401未授权的状态码(通常意味着令牌已失效)。
4. 清理定时器:当检测到令牌失效时,清除定时器并停止进一步的API调用。
下面是一个更加具体的代码示例,它展示了如何在React组件中实现这些步骤:
import React, { useEffect, useState } from 'react';
function MyComponent() {
// 定义API端点和访问令牌
const apiEndpoints = [
'https://api.example.com/endpoint1',
'https://api.example.com/endpoint2',
'https://api.example.com/endpoint3',
'https://api.example.com/endpoint4',
'https://api.example.com/endpoint5'
];
const [accessToken, setAccessToken] = useState('YOUR_ACCESS_TOKEN'); // 确保安全处理令牌
// 定义一个状态变量用于保存定时器ID
const [intervalId, setIntervalId] = useState(null);
const fetchDataGroup = async () => {
try {
await Promise.all(apiEndpoints.map(async (endpoint) => {
const response = await fetch(endpoint, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
if (!response.ok) {
if (response.status === 401) {
throw new Error('Token expired');
} else {
throw new Error(`HTTP error! status: ${response.status}`);
}
}
// 处理成功的响应...
const data = await response.json();
console.log(data);
}));
} catch (error) {
console.error('Error fetching data:', error.message);
if (error.message === 'Token expired') {
handleTokenInvalid();
}
}
};
const handleTokenInvalid = () => {
console.log('Access token is invalid, stopping further requests.');
clearInterval(intervalId); // 清除定时器
// 可能需要在这里做更多处理,比如刷新令牌或让用户重新登录
};
useEffect(() => {
// 设置定时器,开始周期性地调用API
const id = setInterval(fetchDataGroup, 10000); // 每10秒
setIntervalId(id);
// 第一次渲染时立即获取数据
fetchDataGroup();
// 组件卸载时清理定时器
return () => clearInterval(id);
}, []); // 空数组确保仅在首次渲染时运行
return (
<div>
{/* 组件UI */}
</div>
);
}
export default MyComponent;
在这个例子中,fetchDataGroup 函数会发起一组API请求,并使用Promise.all等待所有请求完成。如果任何一个请求失败并且状态码为401,则抛出特定错误,这将触发handleTokenInvalid函数清除定时器。
此外,请注意:
替换'YOUR_ACCESS_TOKEN' 和 API 端点 URL 为实际值。
对于生产环境的应用,应该考虑通过更安全的方式管理访问令牌,例如从环境变量加载或者使用身份验证库来自动刷新令牌。
如果应用有刷新令牌的能力,可以在handleTokenInvalid中尝试刷新令牌而不是直接清除定时器。