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

背景

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

问题

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

扼要代码如下:

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;
});

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JavaScript中,可以通过封装定时器来实现多个组件的定时功能。以下是一个简单的例子: ```javascript // 定义一个封装了定时器组件 function TimerComponent(interval, callback) { this.interval = interval; // 定时器间隔时间 this.callback = callback; // 定时器回调函数 this.timerId = null; // 定时器Id } // 启动定时器 TimerComponent.prototype.start = function() { // 判断定时器Id是否已存在,如果存在则表示已启动过,不再重复启动 if (this.timerId) { return; } // 使用箭头函数确保回调函数内部使用正确的this对象 this.timerId = setInterval(() => { // 调用回调函数 this.callback(); }, this.interval); } // 停止定时器 TimerComponent.prototype.stop = function() { // 清除定时器Id clearInterval(this.timerId); this.timerId = null; } // 创建多个定时器组件实例 var timer1 = new TimerComponent(1000, function() { console.log("定时器1触发"); }); var timer2 = new TimerComponent(2000, function() { console.log("定时器2触发"); }); // 启动定时器 timer1.start(); timer2.start(); // 停止定时器 // timer1.stop(); // timer2.stop(); ``` 以上代码中,我们定义了一个`TimerComponent`对象,该对象包含了一个定时器的间隔时间和回调函数,并且提供了启动和停止定时器的方法。通过创建多个`TimerComponent`实例,每个实例都可以设置不同的定时器间隔和回调函数。调用`start`方法可以启动定时器,调用`stop`方法可以停止定时器。这样,我们就可以通过封装定时器来实现多个组件的定时功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿乐今天敲代码没

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值