收藏
回答

onLanch 还没执行完 , 怎么就执行 onLoad

框架类型 问题类型 终端类型 微信版本 基础库版本
小程序 Bug 客户端 6.5.3 2.0.0

- 当前 Bug 的表现(可附上截图)

onLanch 还没执行完 , 怎么就执行 onLoad


- 预期表现


- 复现路径


- 提供一个最简复现 Demo


回答关注问题邀请回答
收藏

3 个回答

  • 禾店短剧系统
    禾店短剧系统
    2021-05-25

    相信很多人都遇到过这个问题,通常我们会在应用启动app.onLaunch() 去发起静默登录,同时我们需要在加载页面的时候,去调用一个需要登录态的后端 API 。由于两者都是异步,往往page.onload()调用API的时候,app.onLaunch() 内调用的静态登录过程还没有完成,从而导致请求失败。

    解决方案:

    1. 通过回调函数

    // on app.js
    App({
        onLaunch() {
          login()
           // 把hasLogin设置为 true
            .then(() => {
             this.globalData.hasLogin = true;
              if (this.checkLoginReadyCallback) {
                this.checkLoginReadyCallback();
              }
           })
           // 把hasLogin设置为 false
            .catch(() => {
             this.globalData.hasLogin = false;
           });
        },
    });
    
    // on page.js
    Page({
        onLoad() {
          if (getApp().globalData.hasLogin) { // 登录已完成
                fn() // do something
          } else {
                getApp().checkLoginReadyCallback = () => {
                  fn()
                }
          }
        },
    });
    
    


    ⚠️注意:这个方法有一定的缺陷(如果启动页中有多个组件需要判断登录情况,就会产生多个异步回调,过程冗余),不建议采用。




    2. 通过Object.defineProperty监听globalData中的hasLogin值


    // on app.js
    App({
        onLaunch() {
          login()
           // 把hasLogin设置为 true
            .then(() => {
             this.globalData.hasLogin = true;
           })
           // 把hasLogin设置为 false
            .catch(() => {
             this.globalData.hasLogin = false;
           });
        },
       // 监听hasLogin属性
        watchfunction (fn{
            var obj = this.globalData
            Object.defineProperty(obj, 'hasLogin', {
              configurabletrue,
              enumerabletrue,
              setfunction (value{
                this._hasLogin = value;
                fn(value);
              },
              getfunction () {
                return this._hasLogin
              }
            })
        },
    });
    
    // on page.js
    Page({
        onLoad() {
          if (getApp().globalData.hasLogin) { // 登录已完成
                fn() // do something
          } else {
                getApp().watch(() => fn())
          }
        },
    });
    

    3. 通过beautywe的状态机插件(项目中使用该方法)


    // on app.js
    import { BtApp } from '@beautywe/core/index.js';
    import status from '@beautywe/plugin-status/index.js';
    import event from '@beautywe/plugin-event/index.js';
    
    const app = new BtApp({
        onLaunch() {
          // 发起静默登录调用
          login()
    
          // 把状态机设置为 success
            .then(() => this.status.get('login').success())
    
          // 把状态机设置为 fail
            .catch(() => this.status.get('login').fail());
        },
    });
    // status 插件依赖于 beautywe-plugin-event
    app.use(event());
     
    // 使用 status 插件
    app.use(status({
      statuses: [
        'login'
      ],
    }));
    
    // 使用原生的 App 方法
    App(app);
    
    
    // on page.js
    Page({
        onLoad() {
          // must 里面会进行状态的判断,例如登录中就等待,登录成功就直接返回,登录失败抛出等。
          getApp().status.get('login').must().then(() => {
            // 进行一些需要登录态的操作...
          })
        },
    });
    


    具体实现


    具体实现可以参考我的商城小程序项目

    项目体验地址:体验

    代码:代码

    2021-05-25
    有用 1
    回复
  • 夜深
    夜深
    2021-05-20

    解决这个问题,可以看我的这篇文章,提供了3种思路https://developers.weixin.qq.com/community/develop/article/doc/00086219508c28eebf2ce485d56c13

    2021-05-20
    有用
    回复
  • 痛快科技
    痛快科技
    2019-04-26

    小程序很多api都是异步执行的,不会阻塞在某个流程中

    2019-04-26
    有用
    回复
登录 后发表内容