评论

首页 page 加载早于 app.js 等待异步返回数据的解决办法

由于 `isLogin` 这类方法都是向网络发起请求, 通常异步返回信息, 所以当首页 page.onload() 加载的时候还取不到全局设置的用户信息.

我们经常会在 app.js 中完成登录并设置全局的用户信息

// app.js
const
App({
    globalData: {
        userInfo: null
    },
    onLaunch: function () {
        isLogin().then(res => {
            this.globalData.userInfo = res
        })
    },
});

但由于 isLogin 这类方法都是向网络发起请求, 通常异步返回信息, 所以当首页 page.onload() 加载的时候还取不到全局设置的用户信息.

我们可以使用 Promise 或 async/await 的方式来处理异步数据加载问题。这种方法不仅代码清晰易读,而且能够很好地控制异步操作的顺序,确保数据加载完成后再执行后续逻辑。

实现步骤

1. 在 app.js 中使用 Promise 封装异步操作

在 app.js 中,将异步操作(如网络请求)封装成一个 Promise,并在 onLaunch 中调用。

// app.js
const

App({
    globalData: {
        userInfo: null
    },
    onLaunch: function () {
        this.isLogin().then(res => {
            myPage.init(this.globalData)	// 路由守卫
        })
    },
    isLogin() {
        return new Promise((resolve, reject) => {
            isLogin().then(res => {
                this.globalData.userInfo = res
                resolve(res)		// 一定要给个返回, 否则 onLoad 会一直等待
            }).catch((err) => {
                reject(err); 
            });
        })
    }
});

2. 在首页中使用 async/await 等待数据加载

在首页的 onLoad 或 onShow 生命周期中,使用 async/await 等待 app.js 中的数据加载完成。

// pages/index.js
const APP = getApp();
Page({

    data: {
        userInfo: null,
    },

    async onLoad(options) {		// 记得添加 async
        await APP.isLogin()		// await 等待调用完成
        this.setData({
            userInfo: APP.globalData.userInfo
        })
    },

})

为什么推荐这种方法?

  • 明确的数据加载顺序:
    通过 await 确保数据加载完成后再执行后续逻辑,避免了数据未加载完成时的空值问题。
  • 代码可读性高:
    async/await 让异步代码看起来像同步代码,逻辑更清晰,易于理解和维护。
  • 扩展性强:
    如果后续有多个异步操作,可以轻松地通过 Promise.all 或多次 await 来处理。
  • 兼容性好:
    微信小程序原生支持 Promise 和 async/await,无需引入额外的库或工具。

*这是我得最优解! *

最后一次编辑于  02-22  
点赞 0
收藏
评论

1 个评论

  • 拾忆
    拾忆
    02-22

    不是最优解,你有N个页面,不确定用户首次访问是哪个页面的话,每个页面都要先进行await APP.isLogin()吗?

    02-22
    赞同
    回复 2
    • 觀·自在
      觀·自在
      02-23
      不知道还有什么方法
      02-23
      回复
    • 倦鸟
      倦鸟
      02-28
      在封装的网络请求中做前置判断是否登录,这样任意一个页面发起请求都可以await login,当然如果页面没有发起请求,也不需要等待login的回调
      02-28
      回复
登录 后发表内容