标签: 异步请求

  • 微信小程序页面启动,如何获取全局的用户信息

    在微信小程序中,App.onLaunchPage.onLoad 是两个生命周期方法。App.onLaunch 是当小程序启动时触发的方法,而 Page.onLoad 是当页面加载时触发的方法。因为 App.onLaunchPage.onLoad 是异步执行的,有时 Page.onLoad 会在 App.onLaunch 完成之前执行。这可能导致页面在获取用户信息之前就已经加载完成。

    this.userInfoReadyCallback 是一种解决方案,用于处理这种情况。它是一个回调函数,用于在全局数据(例如用户信息)准备就绪时通知页面。

    原理如下:

    1. App.onLaunch 方法中,你会尝试获取用户信息并将其存储到全局变量 globalData.userInfo 中。
    2. 由于 wx.getUserInfo 是一个网络请求,它可能在 Page.onLoad 之后才返回。因此,在 App.onLaunch 中,你可以检查是否已经定义了 this.userInfoReadyCallback。如果已经定义了,说明页面已经加载完毕,并且需要在用户信息准备就绪时接收通知。
    3. 在需要用户信息的页面的 Page.onLoad 方法中,你可以检查全局变量 globalData.userInfo 是否已经存在。如果不存在,说明用户信息还未准备就绪,此时你可以定义 this.userInfoReadyCallback 并将其设置为一个处理用户信息的函数。

    这样,当用户信息准备就绪时,App.onLaunch 方法会调用 this.userInfoReadyCallback,从而通知页面并处理用户信息。这种方法确保了页面在处理用户信息时,不会因为数据未准备就绪而出现错误。

    小程序默认的app.js

    // app.js
    App({
      onLaunch: function () {
        // 展示本地存储能力
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)
    
        // 登录
        wx.login({
          success: res => {
            // 发送 res.code 到后台换取 openId, sessionKey, unionId
          }
        })
    
        // 获取用户信息
        wx.getSetting({
          success: res => {
            if (res.authSetting['scope.userInfo']) {
              // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
              wx.getUserInfo({
                success: res => {
                  // 可以将 res 发送给后台解码出 unionId
                  this.globalData.userInfo = res.userInfo
    
                  // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
                  // 所以此处加入 callback 以防止这种情况
                  if (this.userInfoReadyCallback) {
                    this.userInfoReadyCallback(res)
                  }
                }
              })
            }
          }
        })
      },
      globalData: {
        userInfo: null
      }
    })
    

    如果想确保在page页面能获取用户信息,需要判断`app.globalData.userInfo`是否存在,不存在的话调用app.userInfoReadyCallback

    // pages/somePage/somePage.js
    Page({
      data: {
        userInfo: null
      },
    
      onLoad: function () {
        // 获取全局 App 实例
        const app = getApp();
    
        // 检查全局数据 globalData.userInfo 是否已经存在
        if (app.globalData.userInfo) {
          // 用户信息已经存在,可以直接在页面中使用
          this.setData({
            userInfo: app.globalData.userInfo
          });
        } else {
          // 用户信息不存在,定义一个处理用户信息的函数
          app.userInfoReadyCallback = (res) => {
            this.setData({
              userInfo: res.data.data
            });
          };
        }
      },
    
      // 其他页面方法...
    });