小程序onLaunch执行延迟,导致页面onLoad先执行问题

1,302次阅读
一条评论

共计 1955 个字符,预计需要花费 5 分钟才能阅读完成。

通常,在 app.js 放置一些初始化的登录检测等方法,但是由于 app.js 和 pages 的方法异步执行,如果 app.js 的 onLaunch 执行时间过长,执行未结束时候,页面的 onLoad 已经开始执行,导致 onload 当中无法获取到初始化的一些参数,进而引起首页打开失败,数据加载错误。

网络上其他朋友分享过很多办法,比如增加一个回调函数,或者引入 promise,或者进行 relaunch 等方法,这里我们再提供一个改动较小的办法,就是使用 setInterval 进行循环监听,下方是案例代码:

方法 1、简单粗暴法

该方法的一个好处是无需对原来的 app.js 做任何修改,只需要对 pages 的调用进行一个包裹即可:

onLoad:function(){
        var that = this
        // 假设 app.js 会在缓存中写入 token 值,这里先判断是否已经写入
        if (!wx.getStorageSync('token')) {
        // 如果未写入,则进行一个循环监听等待
            var trynum = 1;
            var watchtoken = setInterval(function () {console.log('第'+trynum+'尝试')
                    if (wx.getStorageSync('token')) {clearInterval(watchtoken)
                        that.getData();}
                    // 超时报错,避免资源长期占用,超时自动停止监听,并弹出错误提醒
                    if (trynum>= 20) {wx.hideLoading()
                        wx.showModal({
                          title: '出错了',
                          content: '系统加载失败, 请联系客服',
                        })
                        clearInterval(watchtoken)
                    }
                    trynum += 1;

                }, 500);
        } else {
            // 如果已经写入了,直接后续操作
            that.getData();}
}

方法 2、Promise

第二种办法比较推荐,首先在 app.js 创建一个登录方法:

login() {
	var that = this
	const isLogin = wx.getStorageSync('token')
	// 如果本地没有存储,表示没有登录,没有登录就要请求,否则不请求
	if (!isLogin) {
		// 开始登录
		return new Promise(function(resolve, reject) {
			// 登录处理逻辑
			if (login) {resolve('登录成功');
			} else {reject('error')
			}
		})
	} else {
		//   已经登录,直接跳过
		console.log('已登录') return new Promise(function(resolve, reject) {resolve()
		})
	}
}

接着就可以在 pages.js 页面进行监控了:

const app = getApp();
// 加载页面
onLoad() {app.login().then(() => {console.log('登录之后执行') 
                        this.getUser();});
},

方法 3、引用钩子插件 spa-custom-hooks

来一段小程序的案例:

// 第一步,安装插件:npm install spa - custom - hooks

// 第二步,入口文件里注册插件:import CustomHook from 'spa-custom-hooks';
const diyHooks = {
	'UserInfo': {
		name: 'UserInfo',
		watchKey: 'userinfo',
		deep: true,
		onUpdate(val) {
			//userinfo 里的 nickName 非空则表示命中此钩子
			return !!val.nickName;
		}
	}
}
//1.vue 架构的注册方式
import store from './store'
Vue.use(CustomHook, diyHooks, store)
//2. 原生小程序的注册方式
// 提前定义 globalData
const globalData = {
	userinfo: {nickName: ''}
}
CustomHook.install(diyHooks, globalData)

// 第三步,业务页面里使用插件(任何页面都可以使用,耦合度低,重复性代码少):onLoadUserInfo() {
	// 可以渲染 canvas 了
	renderCanvas();}

> spa-custom-hooks 是什么

  • 一个可以定制页面钩子的东西,你可以注册全局的异步任务,自己定义钩子的触发条件,满足条件时即可自动执行页面里相关的钩子。
  • 支持和 vue 的原生钩子 created,mounted 等随意搭配使用。
  • 支持 vue 架构(包括 uni-app、wepy、mpvue 等)以及各种小程序。

钩子开源仓库:https://github.com/1977474741/spa-custom-hooks

正文完
加入官方交流QQ群:778957856
post-qrcode
 0
clark
版权声明:本站原创文章,由 clark 于2022-09-04发表,共计1955字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(一条评论)
二月 评论达人 LV.1
2023-10-08 19:08:56 回复

太棒了

 Windows  Chrome