微信小程序onLaunch异步,首页onLoad先执行?


Posted in Javascript onSeptember 20, 2018

本来按照事件顺序,小程序初始化时触发App里的onLaunch,后面再执行页面Page里的onLoad,但是在onLaunch里请求获取是否有权限,等待返回值的时候Page里的onLoad事件就已经执行了。

//app.js
 App({
  onLaunch: function () {
   console.log('onLaunch');
   wx.request({
    url: 'test.php', //仅为示例,并非真实的接口地址
    data: {
    },
    success: function(res) {
     console.log('onLaunch-request-success');
     // 将employId赋值给全局变量,提供给页面做判断
     this.globalData.employId = res.employId;  
    }
   })
  },
  globalData: {
   employId: ''
  }
 })
//index.js
 //获取应用实例
 const app = getApp()
 Page({
  data: {
   albumDisabled: true,
   bindDisabled: false
  },
  onLoad: function () {
   console.log('onLoad');
   console.log('onLoad app.globalData.employId = ' + app.globalData.employId);
   //判断是用户是否绑定了
   if (app.globalData.employId && app.globalData.employId != '') {
    this.setData({
     albumDisabled: false,
     bindDisabled: true
    });
  }
 })

控制台打印的结果是

 onLaunch
 onLoad
 onLoad app.globalData.employId =
 onLaunch-request-success

要是能等完onLaunch请求完再执行Page的onLoad方法那该多好。

这里采用的方法是定义一个回调函数。

Page页面判断一下当前app.globalData.employId是否有值,如果没有(第一次)则定义定义一个app方法(回调函数)app.employIdCallback = employId => {...}。

App页面在请求success后判断时候有Page页面定义的回调方法,如果有就执行该方法。因为回调函数是在Page里面定义的所以方法作用域this是指向Page页面。

//app.js
 App({
  onLaunch: function () {
   wx.request({
    url: 'test.php', //仅为示例,并非真实的接口地址
    data: {
    },
    success: function(res) {
    this.globalData.employId = res.employId;
     //由于这里是网络请求,可能会在 Page.onLoad 之后才返回
     // 所以此处加入 callback 以防止这种情况
     if (this.employIdCallback){
      this.employIdCallback(res.employId);
     }
    }
   })
  },
  globalData: {
   employId: ''
  }
 })
//index.js
//获取应用实例
const app = getApp()
Page({
 data: {
  albumDisabled: true,
  bindDisabled: false
 },
 onLoad: function () {
  //判断是用户是否绑定了
  if (app.globalData.employId && app.globalData.employId != '') {
   this.setData({
    albumDisabled: false,
    bindDisabled: true
   });
  } else {
   // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
   // 所以此处加入 callback 以防止这种情况
   app.employIdCallback = employId => {
    if (employId != '') {
     this.setData({
      albumDisabled: false,
      bindDisabled: true
     });
    }
   }
  }
 }
})

这样的话,就能实现想要的结果。执行顺序就是:

[App] onLaunch -> [Page] onLoad -> [App] onLaunch sucess callback

下面看下小程序_onLaunch异步回调数据加载问题的两种解决方案

问题

小程序开发过程中,会遇到在App启动onLaunch的时候,发起登录请求获取微信用户信息,并注册到我妈自己的服务器上以便使用,然而,这个过程中,

app on launch -> request -> success -> page onload

是无法判断success和page onload哪个先来的,会导致页面初始化数据失败的情况。

解决方案一

就是在request success中处理,使用getCurrentPages方法获取是否页面先于success生成,如果生成我们就强制让页面再次渲染。

这显然是一种hack的方式, 在实际使用过程当中,如果登录逻辑比较复杂,这个方法不是十分便利,page onload在一些特殊情况也会被调用,这显然不是我们想看到的

if (getCurrentPages().length != 0) {
  getCurrentPages()[getCurrentPages().length - 1].onLoad()
}

解决方案二

目前我在开发中使用的是这种方案,

在login的逻辑里,增加一个回调函数cbLoginCallBack。

Page页面判断一下当前app.globalData.sessionKey是否存在,如果没有(第一次)则定义定义一个app方法(回调函数)

// Login Request
if (app.cbLoginCallBack) {
   typeof app.cbLoginCallBack == 'function' && app.cbLoginCallBack(cb_login.data)
  }
// 逻辑页面
if (app.globalData.sessionkey) {
  // init data
} else {
  app.cbLoginCallBack = res => {
    if (res) {
      // init data
    }
  }
}

App页面在请求success后判断时候有Page页面定义的回调方法,如果有就执行该方法。因为回调函数是在Page里面定义的所以方法作用域this是指向Page页面。

总结

以上所述是小编给大家介绍的微信小程序onLaunch异步,首页onLoad先执行?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery ui 1.7更新小结
Aug 15 Javascript
javascript中的作用域scope介绍
Dec 28 Javascript
JavaScript之appendChild、insertBefore和insertAfter使用说明
Dec 30 Javascript
简单的邮箱登陆的提示效果类似于yahoo邮箱
Feb 26 Javascript
js实现鼠标滚轮控制图片缩放效果的方法
Feb 20 Javascript
Bootstrap每天必学之前端开发框架
Nov 19 Javascript
jquery动态添加文本并获取值的方法
Oct 12 Javascript
Angular2表单自定义验证器的实现
Oct 19 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
Jan 20 Javascript
vue的token刷新处理的方法
Jul 17 Javascript
Vue.js中provide/inject实现响应式数据更新的方法示例
Oct 16 Javascript
node.js中fs文件系统模块的使用方法实例详解
Feb 13 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
Sep 20 #Javascript
微信小程序使用gitee进行版本管理
Sep 20 #Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
Sep 20 #jQuery
解决Vue-cli npm run build生产环境打包,本地不能打开的问题
Sep 20 #Javascript
jQuery 点击获取验证码按钮及倒计时功能
Sep 20 #jQuery
Vuex 快速入门(简单易懂)
Sep 20 #Javascript
vue项目打包部署_nginx代理访问方法详解
Sep 20 #Javascript
You might like
PHP使用flock实现文件加锁的方法
2015/07/01 PHP
php微信浏览器分享设置以及回调详解
2016/08/01 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
解决extjs在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
2008/11/06 Javascript
始终在屏幕中间显示Div的代码(css+js)
2011/03/10 Javascript
input输入框的自动匹配(原生代码)
2013/03/19 Javascript
js实现数组去重、判断数组以及对象中的内容是否相同
2013/11/29 Javascript
JSON无限折叠菜单编写实例
2013/12/16 Javascript
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
2014/11/20 NodeJs
JavaScript跨平台的开源框架NativeScript
2015/03/24 Javascript
js实现遍历含有input的table实例
2015/12/07 Javascript
基于jQuery插件实现点击小图显示大图效果
2016/05/11 Javascript
js停止冒泡和阻止浏览器默认行为的简单方法
2016/05/15 Javascript
JS实现淡入淡出图片效果的方法分析
2016/12/20 Javascript
js实现手机拍照上传功能
2017/01/17 Javascript
使用OPENLAYERS3实现点选的方法
2020/09/24 Javascript
layui复选框限制选择个数的方法
2019/09/18 Javascript
JavaScript设计模式之观察者模式与发布订阅模式详解
2020/05/07 Javascript
vue实现简易计算器功能
2021/01/20 Vue.js
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
Python2.5/2.6实用教程 入门基础篇
2009/11/29 Python
Python按行读取文件的实现方法【小文件和大文件读取】
2016/09/19 Python
Django框架用户注销功能实现方法分析
2019/05/28 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
python构造函数init实例方法解析
2020/01/19 Python
用Python在Excel里画出蒙娜丽莎的方法示例
2020/04/28 Python
解决Keras使用GPU资源耗尽的问题
2020/06/22 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
CSS3之背景尺寸Background-size使用介绍
2013/10/14 HTML / CSS
澳大利亚领先的在线机械五金、园艺和存储专家:Edisons
2018/03/24 全球购物
阿拉伯书店:Jamalon
2019/07/24 全球购物
博士生入学考试推荐信
2013/11/17 职场文书
探矿工程师自荐信
2014/01/24 职场文书
2014年小学元旦活动方案
2014/02/12 职场文书
洗发露广告词
2014/03/14 职场文书
做一个有道德的人活动实施方案
2014/08/23 职场文书