uni-app中 setTimeout setInterval冲突问题
uni-app中 setTimeout setInterval冲突问题
示例代码:
按钮2事件
goindenture() {
// 关闭B弹窗
this.closebottompupup()
// 打开C弹窗
setTimeout(() => {
let tempbottom = this.$refs['reftipsbottom'] as TipsBottomComponentPublicInstance
this.showicontype = 'success'
this.showtipposition = 'bottom'
this.showtipnotes = '我是提示内容'
tempbottom.showtips()
}, 300)
},
B页面的关闭动画代码(通过transition-property', 'top'属性实现关闭动画)
this.endmaskopacity = 0
this.openclosetransition(false, 0)
setTimeout(() => {
this.isshow = false
this.isalldone = false
}, 300)
C页面的打开动画代码(通过控制opacity的值用transition-property: opacity;实现)
this.opacityvalue = 1
clearInterval(this.closetiptime)
this.showtiptime = setInterval(() => {
this.opacityvalue = 0
clearInterval(this.showtiptime)
}, 3500)
this.showtiptimelatter = setInterval(() => {
this.isshowtip = false
clearInterval(this.showtiptimelatter)
}, 3800)
操作步骤:
如上代码 建俩自定义组件 然后放上对应代码就行
预期结果:
关闭B页时有动画关闭 打开C页时有动画打开效果
实际结果:
关闭B页面时有关闭动画 打开C时没有打开动画
bug描述:
使用settimeout 和setInterval 分别在两个自定义组件中添加动画效果 会有冲突 例如在A 页点击一个按钮1显示出来B页面 点击A页面上的另一个按钮2时 关闭B页面并打开C页面 其中B页面有3秒的关闭动画 C页面打开时有3秒的动画 所以点击按钮2时先关闭B页面 然后延迟3秒打开C页 结果是B页面有动画 C页面没有动画了 只有B页有关闭动画 注释关闭B页操作 仅保留C页的打开动画是有效果的
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | win10 专业版 | HBuilderX |
uni-app x/App | ||
Android | Android 13 | |
华为 mate60 | ||
vue | vue3 | |
HBuilderX | 4.24 |
你好, 用hbuilderX创建一个demo项目,然后将demo工程用附件的形式上传吧 。 这样比较好排查
在uni-app中,setTimeout
和 setInterval
的冲突问题通常是由于它们在不同环境下的行为差异或由于不恰当的清理操作导致的。在uni-app(尤其是在小程序和App端)中,这些定时器函数的行为可能会因为平台的差异而有所不同。以下是一些示例代码,展示了如何在uni-app中正确使用这些定时器,并处理潜在的冲突。
示例代码:正确使用 setTimeout
和 setInterval
1. 使用 setTimeout
Page({
onLoad() {
this.timeoutHandler = setTimeout(() => {
console.log('This message is logged after 2 seconds');
}, 2000);
},
onUnload() {
// 页面卸载时清理定时器
clearTimeout(this.timeoutHandler);
}
});
2. 使用 setInterval
Page({
data: {
counter: 0
},
onLoad() {
this.intervalHandler = setInterval(() => {
this.setData({
counter: this.data.counter + 1
});
}, 1000);
},
onUnload() {
// 页面卸载时清理定时器
clearInterval(this.intervalHandler);
}
});
处理潜在的冲突
避免重复设置定时器
为了确保不会重复设置定时器,可以在设置新定时器前检查是否已经存在定时器。
Page({
data: {
intervalHandler: null
},
startInterval() {
if (this.data.intervalHandler) return; // 如果已经存在定时器,则不重复设置
this.setData({
intervalHandler: setInterval(() => {
console.log('Interval is running');
}, 1000)
});
},
stopInterval() {
const { intervalHandler } = this.data;
if (intervalHandler) {
clearInterval(intervalHandler);
this.setData({ intervalHandler: null });
}
}
});
小程序特有注意事项
在小程序中,如果页面被销毁(例如用户导航到另一个页面),但定时器尚未被清理,这可能会导致内存泄漏或执行错误的代码。因此,务必在页面的生命周期函数(如onUnload
)中清理定时器。
结论
在uni-app中使用setTimeout
和setInterval
时,关键在于正确地管理定时器的生命周期。通过在页面卸载时清理定时器,可以避免潜在的冲突和内存泄漏问题。同时,注意检查定时器是否已经存在,以避免重复设置。上述代码示例展示了如何在uni-app中安全地使用这些定时器函数。