多页面使用同个带定时器的组件,多次切换路由定时器叠加无法彻底消除

背景

多个页面仅调用接口不同,功能相似

问题

多个路由使用了一个组件,该组件中需要定时调用接口,切换路由时观察接口发现存在多个定时器,且另一个页面的定时器并未消除

扼要代码如下:

const props = defineProps({
    
    
//接收函数
	request: {
    
    
		type: Function,
		default: undefined
	}
});
const resolveListRequest = async requestInstance => {
    
    
	if (typeof props.request !== 'function') return;
	const request = requestInstance({
    
    
		page: queryParams.page,
		size: queryParams.size,
		keyword: queryParams.keyword
	});
	return request instanceof Promise ? await request : request;
};
//页面分页接口以及定时器
const getList = async () => {
    
    
	const requestInstance = props.request;
	if (typeof requestInstance !== 'function') return;
	const data = await resolveListRequest(requestInstance);
	if (!data) return;
	list.value = data.list;
	total.value = data.total;
	timer = setTimeout(async function () {
    
    
		await getList();
	}, 1000);
};
onMounted(() => {
    
    
	if (props.request) {
    
    
		getList();
	}
});
// 清除定时器
onUnmounted(() => {
    
    
	timer && clearTimeout(timer);
});

解决办法

我们知道setTimeout会等待调用结束后才会发起下一次调用,通过不断debug我们发现,当发起新的一次接口请求但是接口还未有返回值时,组件已经调用了onUnmounted并清除了之前的定时器,组件完成了使命,但是紧接着接口吐出了返回值并又生成了新的定时器,导致定时器无法被彻底清除的问题,所以我们需要保证 在清除掉所有的定时器后当前组件不会再有接口调用
因此,我们可以——

设置标识isclear判断定时器是否消除,虽然笨了点,但是简单有效

let isclear = false;
const getList = async () => {
    
    
	if (isclear) return;
	const requestInstance = props.request;
	if (typeof requestInstance !== 'function') return;
	const data = await resolveListRequest(requestInstance);
	if (!data) return;
	list.value = data.list;
	total.value = data.total;
	timer = setTimeout(async function () {
    
    
		await getList();
	}, 1000);
};
// 清除定时器
onUnmounted(() => {
    
    
	timer && clearTimeout(timer);
	isclear = true;
});

猜你喜欢

转载自blog.csdn.net/qq_45840993/article/details/129799403