请教微信小程序维护登录态怎么使用Promise改写?

  1. 业务需求是,维护登录态的代码写在app.js里的,获取到登录态后保存到globaldata里,子页面的请求接口都需要携带登录态,直接拿globaldata里的登录态就可以。
  2. 遇到的问题是,经常子页面比如index页面里的代码在app.js执行完毕前就执行,就拿不到globaldata里的登录态。
  3. 我的思路是能不能把app.js里维护登录态的代码用Promise改写一下,然后把Promise实例放到globaldata里,子页面比如index页面取globaldata的Promise实例等待状态变为resolve时就可以拿到登录态然后再请求接口了。

下面是我回调函数方式维护登录态的大体流程:请教大佬怎么改写呢?

wx.getStorage({ // Storage里取登录态
  key: 'loginState',
  success(res) { // 登录态存在
    wx.checkSession({
      success() {
        //session_key 未过期
      },
      fail() {
        // session_key 已经失效,需要重新执行登录流程
        wx.login({
          success(val){
            wx.request({
              url: 'https://test.com/onLogin',
              data: {
                code: val.code
              },
              success(data){
                this.globalData.uid = data.uid; // 将后端返回的登录态uid保存到globalData方便子页面使用
              }
            })
          }
        }) //重新登录
      }
    })
  },
  fail() {
    wx.login() //登录态不存在,重新登录
  }
})
阅读 3.1k
4 个回答

当然是可以的,不过不一定非要用 globalData,实际上整个 app 实例都可以访问,而且是个普通对象,所以你可以把这个 Promise 直接放在 app 的任何位置,比如:

// app.js
App({
  loginPromise: null,
  onLaunch() {
    // 假设在 `checkSession` 里,你
    // 1. 验证用户登录状态
    // 2. 获取用户信息
    // 3. 并且把数据放到该放的地方
    this.loginPromise = checkSession();
  },
});

// pages/index/index.js
const app = getApp();

Page({
  onLoad() {
    // 其它的初始化动作
    // 使用 app 里的 promise
    app.loginPromise
      .then(user => {
        // 处理用户身份
        // 处理完成之后,然后启动
        this.doStart();
      });
  },
  doStart() {
    // 启动函数
  },
});

写完答案我又看了眼你的问题,你知道怎么写 Promise 吧?

目前我觉得最好的方式:封装一个请求接口,每次发送请求先检查登录状态,如果没登录就先请求 session,再发送请求。这样对于页面来说,就不必关心登录状态了。以下代码仅供参考:

function request2 (method, url, data) {
    const session = getSession()
    
    if (!session) {
        return requestSession().then((res) => {
            setSession(res.session)
            return request(method, url, data, res.session)
        })
    } else {
        return request(method, url, data, session)
    }
}

// page.js
Page({
    onLoad () {
        request2('get', 'list', { page: 2 })
    }
})

可以参考 WeRequest
解决繁琐的小程序会话管理,一款自带登录态管理的网络请求组件

内部实现了 Promise,代码组织 和 架构都很不错,无论学习和使用都是很好的

    class Ready {
        constructor (pro) {
            this.successQueue = {}
            this.failQueue = {}
            this.id = 1
            this.isSuccess = false
            this.isFail = false
            this.successInfo = void 0
            this.failInfo = void 0
            this.startFetch(pro)
        }
        ready (fn) {
            if (this.isSuccess) {
                setTimeout(() => {
                    fn(this.successInfo)
                }, 0)
            } else {
                this.successQueue[this.id++] = fn
            }
            return this
        }
        fail (fn) {
            if (this.isFail) {
                setTimeout(() => {
                    fn(this.failInfo)
                }, 0)
            } else {
                this.failQueue[this.id++] = fn
            }
            return this
        }
        updateReady (data) {
            Object.keys(this.successQueue).forEach(key => {
                this.successQueue[key](data)
                delete this.successQueue[key]
            })
        }
        updateFail (data) {
            Object.keys(this.failQueue).forEach(key => {
                this.failQueue[key](data)
                delete this.failQueue[key]
            })
        }
        startFetch (pro) {
            pro.then(data => {
                this.isSuccess = true
                this.updateReady(data)
                this.successInfo = data
            }).catch(err => {
                this.isFail = true
                this.updateFail(err)
                this.failInfo = err
            })
        }
    }
    function init (pro) {
        return new Ready(pro)
    }
    
    let pro = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
        }, 5000)
    })
    let wait = init(pro)
    wait.ready((info) => {
        console.log(info)
    })
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题