我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…
最近在使用uniapp开发微信小程序中,需要增加一个首屏广告功能,三秒后跳转首页也可以点击跳过,本来一个很简单功能,使用setTimeout设置三秒后跳转,并且保存定时器编号,如果点跳过,则使用clearTimeout清除该定时器,但是却遇到一个bug,那就是在首次进入小程序后,点击跳过clearTimeout并不能够清理掉定时器编号,因此翻阅文档,发现我们需要在
onHide,onUnload中进行清除,但是背后的原因驱使我重新阅读了一遍小程序文档,更深入了解其原理。
- onLoad中setTimeout自动跳转
data() {
return {
timer:'',
}
},
async onLoad(option) {
this.timer=setTimeout(()=>{
uni.reLaunch({
url:'/index'
})
},3000)
}
- 点击跳转
点击跳转清除定时器并跳转至首页,但在初次进入时,清除定时器并不生效
handleToIndex(){
// if(this.timer!==''){
//clearTimeout(this.timer);
//}
uni.reLaunch({
url:'/index'
})
}
- 解决方案
在
onHide,onUnload中清除定时器
onHide() {
clearTimeout(this.timer);
},
onUnload(){
clearTimeout(this.timer);
},
那么造成这个bug的原因是什么呢,可以从小程序的线程即逻辑层服务及其页面生命周期来研究, 小程序在运行环境中分为逻辑层与渲染层, WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。 小程序的渲染层和逻辑层分别由2个线程管理, AppService负责逻辑层的运行,使用
JavaScript引擎为小程序提供开发者JavaScript代码的运行环境以及微信小程序的特有功能,所有代码最终将会打包成一份JavaScript文件,并在小程序启动的时候运行,直到小程序销毁。
-
小程序的渲染层及逻辑层
-
小程序页面生命周期
小程序以栈的形式维护页面,随着路由的切换,页面不断进栈出栈,触发生命周期。
当我们切换路由,页面发生切换时,小程序会回收部分页面,从而造成使用方法的形式进行定时器编号清除会失败。因此我们需要在页面的生命周期中进行定时器编号的清除。
在生命周期中清除定时器,我们要根据页面会触发的生命周期进行选择,最后选择为
onUnload: 监听页面卸载,onHide:当小程序从前台进入后台
- 小程序页面切换会触发的生命周期