微信小程序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 相关文章推荐
javascript div 遮罩层封锁整个页面
Jul 10 Javascript
将函数的实际参数转换成数组的方法
Jan 25 Javascript
js+css在交互上的应用
Jul 18 Javascript
使用jQuery插件创建常规模态窗口登陆效果
Aug 23 Javascript
js处理自己不能定义二维数组的方法详解
Mar 03 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
Mar 20 Javascript
html文本框提示效果的示例代码
Jun 28 Javascript
JavaScript实现简单的日历效果
Sep 25 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
Feb 22 Javascript
微信小程序显示下拉列表功能【附源码下载】
Dec 12 Javascript
js取小数点后两位四种方法
Jan 18 Javascript
vue实现鼠标经过动画
Oct 16 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
无线电广播与收音机发展的历史回眸
2021/03/02 无线电
php上传、管理照片示例
2006/10/09 PHP
PHP json格式和js json格式 js跨域调用实现代码
2012/09/08 PHP
PHP获取一个字符串中间一部分字符的方法
2014/08/19 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
php+mysqli使用面向对象方式查询数据库实例
2015/01/29 PHP
ThinkPHP里用U方法调用js文件实例
2015/06/18 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
2018/05/23 PHP
PHP PDOStatement::nextRowset讲解
2019/02/01 PHP
php防止表单重复提交实例讲解
2019/02/11 PHP
纯原生js实现table表格的增删
2017/01/05 Javascript
深入nodejs中流(stream)的理解
2017/03/27 NodeJs
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
vue.js 实现图片本地预览 裁剪 压缩 上传功能
2018/03/01 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
[05:31]DOTA2英雄梦之声_第04期_光之守卫
2014/06/23 DOTA
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
python实现简单ftp客户端的方法
2015/06/28 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
python如何压缩新文件到已有ZIP文件
2018/03/14 Python
Pandas之ReIndex重新索引的实现
2019/06/25 Python
numpy 返回函数的上三角矩阵实例
2019/11/25 Python
使用pytorch完成kaggle猫狗图像识别方式
2020/01/10 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
pygame用blit()实现动画效果的示例代码
2020/05/28 Python
HTML5 progress和meter控件_动力节点Java学院整理
2017/07/06 HTML / CSS
html5 canvas fillRect坐标和大小的问题解决方法
2014/03/26 HTML / CSS
BrandAlley英国:法国折扣奢侈品网上零售商
2017/07/03 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
民生工程实施方案
2014/03/22 职场文书
2015年优质护理服务工作总结
2015/04/08 职场文书
紧急迫降观后感
2015/06/15 职场文书
2016廉洁从业学习心得体会
2016/01/19 职场文书
《我是什么》教学反思
2016/02/16 职场文书
python基础之爬虫入门
2021/05/10 Python