zoukankan      html  css  js  c++  java
  • 微信小程序之onLaunch与onload异步问题

    来源:https://www.cnblogs.com/Can-daydayup/p/10614399.html

    异步有好处,也有不好的地方,小程序开发,如果从网络调取数据,而且,这个数据在几处用到,那么,很有可能存在本文所说的问题。

    文章正文:

    所述问题:

       前端时间开发了一个微信小程序商城项目,因为这个项目我们的需求是进入小程序就通过wx.login({}) 这个api进行用户登录,获取系统后台的用户基本信息。再此之前,一直以为微信小程序中的App.js 中onLaunch (小程序初始化完成执行该方法)方法比其他页面的的 onload 方法要先执行。那么问题就来了,我每次进入小程序首页的时候有时候会先执行onlaunch方法,有时又会先执行首页的onload的方法,最后经过确定,在微信小程序中这两个方法并没有执行先后的顺序,因为他们都是异步执行的。当然开发过微信小程序的开发者都知道微信请求数据都是异步执行的,如在同一个onload写两个请求数据的方法,它不一定会按照先后顺序去执行,这就是传说中的异步地狱了。

    解决方法:

      当然,我既然知道这个执行顺序是由于微信小程序的异步执行请求原因导致的。我们可以使用Promise 来解决异步编程问题啦。我的解决方法是,首先我是在app.js 中定义了一个全局方法,用来登录小程序请求用户信息的接口,每次进入首页的时候先判断我是否已有用户信息缓存,假如不存在那么请求app.js中的全局方法进行数据获取。在这里我就不详细介绍Promise 的基本用法了,因为阮一峰已经将的非常详细了,大家可以点击查看【http://es6.ruanyifeng.com/#docs/promise#Promise-all】。

    方法实现:

    App.js方法实现:

    复制代码
    App({
    onLaunch: function() {
    console.log('App Launch')
    //不在这里默认请求
    },
    /**
    * 定义全局变量
    */
    globalData: {
    openid: '', //用户openid
    userId: '', //用户编号
    },
    /**
    * 用户登录请求封装(解决onlaunch和onload执行顺序问题)
    */
    userLogin: function() {
    var that = this;
    //定义promise方法
    return new Promise(function(resolve, reject) {
    // 调用登录接口
    wx.login({
    success: function(res) {
    if (res.code) {
    console.log("用户登录授权code为:" + res.code);
    //调用wx.request请求传递code凭证换取用户openid,并获取后台用户信息
    wx.request({
    url: 'https://www.xxxx.xxx.api', // 后台请求用户信息方法【注意,此处必须为https数字加密证书】
    data: {
    code: res.code //code凭证
    },
    header: {
    'content-type': 'application/json' // 默认值
    },
    success(res) {
    console.log(res.data)
    if (res.data.errcode == 0) {
    //获取用户信息成功
    that.globalData.openid = res.data.openid;
    that.globalData.userId = res.data.UserId;
    //存入session缓存中
    wx.setStorageSync("userId", that.globalData.userId)
    console.log(that.globalData.userId);
    console.log(that.globalData.openid);
    //promise机制放回成功数据
    resolve(res.data);
    } else {
    reject('error');
    }
    },
    fail: function(res) {
    reject(res);
    wx.showToast({
    title: '系统错误'
    })
     },
    complete: () => {
    
    } //complete接口执行后的回调函数,无论成功失败都会调用
    })
    } 
    else
    { reject("error"); } } }) }) }
    });
    复制代码

    index.js实现:

    复制代码
    const app=getApp();//初始化app.js
    page({
    
    onLoad: function (option) {
    var that = this;
    let UserId = wx.getStorageSync("userId");
    console.log("进入首页的用户编号为:" + UserId);
    if (UserId == '') {
    app.userLogin().then(res => {
    console.log("promise回调后的数据:");
    console.log(res);
    if (res.errcode == 0) {
    //把首页需要请求的数据接口都提取到一个自定义方法中
    that.GetData();
    }
    })
    }
    else
    {
    //用户缓存存在
    that.GetData();
    }
    
    }
    ,
    GetData()
    {
    //需要用到用户编号换取商品信息的接口
    
    }
    })
    复制代码

    总结:

      当然解决异步回调的方法有很多种,不过我在这里只说我认为好用的一种,大家有什么想法也可以一起分享学习。

  • 相关阅读:
    CodeForces 156B Suspects(枚举)
    CodeForces 156A Message(暴力)
    CodeForces 157B Trace
    CodeForces 157A Game Outcome
    HDU 3578 Greedy Tino(双塔DP)
    POJ 2609 Ferry Loading(双塔DP)
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛十六进制转换成十进制
  • 原文地址:https://www.cnblogs.com/cblx/p/12924694.html
Copyright © 2011-2022 走看看