鹅鹅鹅鹅
鹅鹅鹅鹅
  • 发布:2022-01-12 14:29
  • 更新:2024-02-04 14:36
  • 阅读:3362

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

分类:uni-app

场景:

大家项目中应该都存在这样的场景,在onLaunch里用wx.login拿到code,再用code去发送请求获取token、用户信息等,整个过程都是异步的,然后我们在页面里onLoad去用的时候异步请求还没回来,导致没拿到想要的数据,以往要么监听是否拿到,要么自己封装一套回调,总之都挺麻烦,每个页面都要写一堆无关当前页面的逻辑。

直接上终极解决方案,公司内部已接入一年很稳定:

1.可完美解决异步问题

2.使用方便

3.可灵活定制异步钩子

4.采用监听模式实现,接入无需修改以前代码

5.支持各种小程序和vue架构

。。。

//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  
    },  
    onReadyShowUser(){  
        //小程序内页面渲染完成 && 页面显示 && 拿到用户信息  
        //Tips:适用于需要获取小程序组件或者dom,并且每次页面显示都会执行的场景,例如,每次显示页面的时候都要拿到最新的头像去渲染到canvas上面  
    },  
})

具体文档和Demo见↓

Github:https://github.com/1977474741/spa-custom-hooks

祝大家用的愉快,记得star哦

2 关注 分享
j***@qq.com 1***@qq.com

要回复文章请先登录注册

9***@qq.com

9***@qq.com

没有我的方案好
2024-02-04 14:36
l***@163.com

l***@163.com

什么时候 支持uniapp+v3+vite+ts 项目
2023-04-25 16:24
鹅鹅鹅鹅

鹅鹅鹅鹅 (作者)

回复 5***@qq.com :
目前还不支持v3
2023-04-07 16:08
鹅鹅鹅鹅

鹅鹅鹅鹅 (作者)

回复 赵永强 :
概念不一样的,一个是支持扩展配置的自定义钩子,是指在到达某个生命周期时机或满足某个条件自动触发。
一个是单纯的通知功能,跟生命周期没关系,首先你需要手动去通知,其次如果你的逻辑依赖某生命周期,你要去处理你的数据和生命周期之间的关系,再去通知。
2023-04-07 16:07
赵永强

赵永强

直接uni.$emit和uni.$on就解决了
2023-03-30 17:26
5***@qq.com

5***@qq.com

v3咋用
2023-03-30 17:02
鹅鹅鹅鹅

鹅鹅鹅鹅 (作者)

回复 5***@qq.com :
不是await阻塞的问题,是在onShow里面去请求数据的话,先走onShow再走请求,就成了串行的。
他们本来可以并行的,请求的发起无需等待onShow的,就像Promise.all一样,内部promise无需互相等待,只需要一个共同完成的结果。
2022-07-06 17:24
5***@qq.com

5***@qq.com

回复 鹅鹅鹅鹅 :
那走异步,.then(res=>()) 这样获取,就不堵塞了
2022-07-04 11:17
鹅鹅鹅鹅

鹅鹅鹅鹅 (作者)

回复 5***@qq.com :
这样能解决onShow里面去用user不报错的问题,原理是走了onShow再去获取用户信息,这样其实是把其他逻辑滞后了,它们本来是可以并行占用时间更少的
2022-06-27 14:31
5***@qq.com

5***@qq.com

封装一个 users 方法挂到 uni.$xxx ,在 onShow await uni.$xxx.users() ,这样就可以了。
2022-06-16 17:23