场景:
在小程序中大家应该都有这样的场景,在onLaunch里用wx.login静默登录拿到code,再用code去发送请求获取token、用户信息等,整个过程都是异步的,然后我们在业务页面里onLoad去用的时候异步请求还没回来,导致没拿到想要的数据,以往要么监听是否拿到,要么自己封装一套回调,总之都挺麻烦,每个页面都要写一堆无关当前页面的逻辑。
直接上终极解决方案,公司内部已接入两年很稳定:
1.可完美解决异步问题
2.不污染原生生命周期,与onLoad等钩子共存
3.使用方便
4.可灵活定制异步钩子
5.采用监听模式实现,接入无需修改以前相关逻辑
6.支持各种小程序和vue架构
。。。
//为了简洁明了的展示使用场景,以下有部分是伪代码,请勿直接粘贴使用,具体使用代码看Github文档
//app.js
//globalData提出来声明
let globalData = {
// 是否已拿到token
token: '',
// 用户信息
userInfo: {
userId: '',
head: ''
}
}
//注册自定义钩子
import CustomHook from 'spa-custom-hooks';
CustomHook.install({
'Login':{
name:'Login',
watchKey: 'token',
onUpdate(token){
//有token则触发此钩子
return !!token;
}
},
'User':{
name:'User',
watchKey: 'userInfo',
onUpdate(user){
//获取到userinfo里的userId则触发此钩子
return !!user.userId;
}
}
}, globalData)
// 正常走初始化逻辑
App({
globalData,
onLaunch() {
//发起异步登录拿token
login((token)=>{
this.globalData.token = token
//使用token拿用户信息
getUser((user)=>{
this.globalData.user = user
})
})
}
})
//关键点来了
//Page.js,业务页面使用
Page({
onLoadLogin() {
//拿到token啦,可以使用token发起请求了
const token = getApp().globalData.token
},
onLoadUser() {
//拿到用户信息啦
const userInfo = getApp().globalData.userInfo
},
onReadyUser() {
//页面初次渲染完毕 && 拿到用户信息,可以把头像渲染在canvas上面啦
const userInfo = getApp().globalData.userInfo
// 获取canvas上下文
const ctx = getCanvasContext2d()
ctx.drawImage(userInfo.head,0,0,100,100)
},
onShowUser() {
//页面每次显示 && 拿到用户信息,我要在页面每次显示的时候根据userInfo走不同的逻辑
const userInfo = getApp().globalData.userInfo
switch(userInfo.sex){
case 0:
// 走女生逻辑
break
case 1:
// 走男生逻辑
break
}
}
})
具体文档和Demo见↓
Github:https://github.com/1977474741/spa-custom-hooks
祝大家用的愉快,记得star哦
以后就用这个方案了
用上了,感谢up!!
确实这两年想过用很多方法,查看了promise的实现,做过多模块用同时登录,返回同一个promise,试过每个页面设置重新查找登录,都不好实现,楼主做得确实好!
这个解决方案简直太棒了,不过好奇你是怎么把那些更新的函数加到每个页面中的?
使用下来,比较麻烦。直接自动登录后,获取当前page,调用page.onShow()方法比较简单粗暴。(把跟登录相关需要更新的方法调用写在onShow里)
还有如果你的项目比较简单,场景特别单一,而且也不用考虑扩展性的话,那其实只要能实现效果,怎样都行。
1.和原生钩子耦合问题。
2.应用场景比较单一,不易扩展。
3.不能组合使用,不灵活。
当然这三点都不是实现一个需求的必要条件,所以。。还是自己看情况用哪种比较合适
必须赞一个
Promise赞一个
牛,这是我苦苦追寻多年的答案,想问下大佬是在深圳工作吗?
优秀
优秀