评论

小程序app.onLaunch与page.onLoad异步问题的最佳实践

app.onLaunch与page.onLoad异步问题终极解决方案

场景:

在小程序中大家应该都有这样的场景,在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哦

最后一次编辑于  2023-04-23  
点赞 65
收藏
评论

52 个评论

  • vking
    vking
    2022-06-15

    优秀

    2022-06-15
    赞同 1
    回复 1
    • Q.ZHANG
      Q.ZHANG
      2022-06-16
      感谢支持
      2022-06-16
      回复
  • 梁大新🍃
    梁大新🍃
    2022-06-13

    确实不错

    2022-06-13
    赞同 1
    回复 1
    • Q.ZHANG
      Q.ZHANG
      2022-06-13
      感谢支持
      2022-06-13
      回复
  • U.K
    U.K
    2022-04-04

    看起来不错的样子,先收藏了

    2022-04-04
    赞同 1
    回复
  • 李艺
    李艺
    2022-03-29

    手动点赞

    2022-03-29
    赞同 1
    回复 1
    • Q.ZHANG
      Q.ZHANG
      2022-03-30
      感谢支持
      2022-03-30
      回复
  • 结冰水
    结冰水
    2022-01-18

    我在第一步引入的时候就已经报错了,module is not defined,我有些想不通

    2022-01-18
    赞同 1
    回复 6
    • Q.ZHANG
      Q.ZHANG
      2022-01-18
      原生小程序是吧?有构建npm吗
      2022-01-18
      回复
    • 结冰水
      结冰水
      2022-01-18
      解决了,是我没有构建npm
      2022-01-18
      回复
    • 结冰水
      结冰水
      2022-01-19回复Q.ZHANG
      感谢楼主的奉献,是真的好用,尤其是对我这种小白
      2022-01-19
      回复
    • Q.ZHANG
      Q.ZHANG
      发表于小程序端
      2022-01-20回复结冰水

      哈哈,那就帮忙多宣传,让大家都知道有这么个东西,多谢了您内!

      2022-01-20
      回复
    • 富途熊熊
      富途熊熊
      2022-01-20
      引入时候没有报错,但最后也报了module not defined, npm搭建感觉也是对的,不太清楚为什么?
      2022-01-20
      回复
    查看更多(1)
  • xplee
    xplee
    2022-01-11

    赞一个

    2022-01-11
    赞同 1
    回复 1
    • Q.ZHANG
      Q.ZHANG
      2022-01-11
      感谢支持
      2022-01-11
      回复
  • 王浩Hanks🇨🇳
    王浩Hanks🇨🇳
    2022-01-10

    点赞收藏加评论

    2022-01-10
    赞同 1
    回复 1
    • Q.ZHANG
      Q.ZHANG
      2022-01-11
      感谢支持
      2022-01-11
      回复
  • 胃里养了只霸王龙
    胃里养了只霸王龙
    2022-01-10

    我们目前用的广播。。

    2022-01-10
    赞同 1
    回复 29
    • Q.ZHANG
      Q.ZHANG
      2022-01-10
      哈哈,你用这个试试,用完绝对真香,注册的钩子可以随意组合,这东西解决的不只是某个异步回调的问题,甚至还能这么用onReadyShowUser,意思就是渲染完成+每次显示页面+拿到用户信息
      2022-01-10
      回复
    • Q.ZHANG
      Q.ZHANG
      2022-01-10
      钩子配置好之后就一劳永逸了,跟使用普通生命周期一样简单方便
      2022-01-10
      回复
    • 胃里养了只霸王龙
      胃里养了只霸王龙
      2022-01-10回复Q.ZHANG
      我们目前只需要,app.js监听定位改变后能通知各个页面进行同步更新列表数据。用broadcast能解决80%的问题。
      2022-01-10
      回复
    • Q.ZHANG
      Q.ZHANG
      2022-01-10回复胃里养了只霸王龙
      我们之前也是有这个需求,要监听用户授权到位置后通知页面更新数据,不过还要其他的类似需求,比如登录态、用户信息,全局配置,全都是异步的,所以写了这玩意,有兴趣可以试试,比broadcast好用
      2022-01-10
      回复
    • 胃里养了只霸王龙
      胃里养了只霸王龙
      2022-01-10回复Q.ZHANG
      可以试下。
      2022-01-10
      回复
    查看更多(24)
  • 拜拜
    拜拜
    11-25

    uni.app 怎么处理啊...?我再onLaunch里登录 首页需要获取用户数据,但到首页的时候 已经加载完了,数据还没拿到

    11-25
    赞同
    回复
  • locter
    locter
    06-09

    会出现一些错误


    我原来的 userinfo 里面也是有数据的

    06-09
    赞同
    回复 3
    • locter
      locter
      06-09
      直接 app.globalData.userinfo = {} 也会出现这个错误,由于项目需要,我在尽可能避免,globalData 的引用丢失,所以一直在以深度合并的方式去做。
      06-09
      回复
    • Q.ZHANG
      Q.ZHANG
      06-18回复locter
      初始化的时候监听的是哪个引用,globalData还是globalData.userinfo
      06-18
      回复
    • locter
      locter
      06-18回复Q.ZHANG
      globalData
      06-18
      回复

正在加载...

登录 后发表内容