初学微信小程序,总是搞不清app和page生命周期函数的执行先后顺序,尤其是在登陆授权个人信息这一板块,最近老是出现问题,所以本人仔细撸了一下代码,下面是自己的一些见解。因为刚接触小程序,见解不深,或者有错误的地方还请谅解,并帮忙指正。
建议在看我写的东西时,先看一下文章微信小程序不支持wx.getUserInfo授权的解决方法。我感觉他的文章还是写的比较完整的,对于新学者也是好理解的。好,废话不多说,大家还是喜欢用代码说话的。注意我打console的位置,还有文笔不好,见谅
app.js
onLaunch: function (options) {
console.log('刚进入onLaunch内部');
// 展示本地存储能力
var that = this;
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 获取用户信息
wx.getSetting({
success: res => {
console.log('app.getSetting异步返回数据');
var that = this;
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
console.log('app.getUserInfo异步返回数据');
// 可以将 res 发送给后台解码出 unionId
that.globalData.userInfo = res.userInfo;
that.globalData.iv = res.iv;
that.globalData.encryptedData = res.encryptedData;
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (that.userInfoReadyCallback) {
that.userInfoReadyCallback(res)
}
}
})
}
}
});
},
index.js
onLoad: function(options) {
console.log('刚进入page.onLoad');
console.log(this.data.canIUse);
var that = this;
wx.showShareMenu({
withShareTicket: true
});
that.setData({
sharedOptions: options
})
if (options.uid != undefined || options.uid != null) {
that.setData({
otherId: options.uid,
});
}
if (app.globalData.userInfo) {
console.log('page.onLoad 第一个条件');
that.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
});
if (that.data.uid == null) {
that.setData({
loadingShow: true
})
that.time(); //调用倒计时,5秒后请求数据
that.code(); //登录接口
}
} else if (that.data.canIUse) {
console.log('page.onLoad 第二个条件');
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
console.log('回调函数');
that.setData({
hasUserInfo: true
});
if (that.data.uid == null) {
that.setData({
loadingShow: true
})
that.time(); //调用倒计时,5秒后请求数据
that.code(); //登录接口
}
}
} else {
console.log('page.onLoad 第三个条件');
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo
that.setData({
hasUserInfo: true
});
if (that.data.uid == null) {
that.setData({
loadingShow: true
});
that.time(); //调用倒计时,5秒后请求数据
that.code(); //登录接口
}
}
})
};
},
//点击授权
getUserInfo: function(e) {
var that = this;
if (e.detail.userInfo != undefined) {
wx.getSetting({
success: res => {
var that = this;
if (res.authSetting['scope.userInfo']) {
console.log('index点击授权');
console.log(that.data.canIUse);
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
app.globalData.userInfo = res.userInfo;
app.globalData.iv = res.iv;
app.globalData.encryptedData = res.encryptedData;
if (that.data.uid == null) {
that.setData({
loadingShow: true
});
that.time(); //调用倒计时,5秒后请求数据
that.code(); //登录接口
}
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (that.userInfoReadyCallback) {
that.userInfoReadyCallback(res)
}
}
})
}
}
})
this.setData({
hasUserInfo: true,
})
} else {
wx.showModal({
title: '警告',
content: '您点击了拒绝授权,将无法正常使用7k7k的功能体验。',
// success: function (res) {
// if (res.confirm) {
// wx.openSetting({
// success: function (res) {
// if (!res.authSetting["scope.userInfo"] || !res.authSetting["scope.userLocation"]) {
// //这里是授权成功之后 填写你重新获取数据的js
// //参考:
// that.getLogiCallback('', function () {
// callback('');
// })
// }
// }
// })
// }
// }
})
}
},
onShow: function() {
console.log('page.onShow');
var that = this;
if (app.globalData.uid != null) {
that.setData({
money: app.globalData.money,
gameList: app.globalData.gameList
})
that.pageInitialization(); //获取栏目
that.indexData(); //获取用户信息
that.friendList(); //邀请成功列表
that.shaerPage(); //分享页面跳转
}
},
// 获取临时code
code: function() {
console.log('临时code');
var that = this;
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId’
app.globalData.code = res.code; //临时code
wx.request({
url: app.globalData.URL + '/api.php?c=system&do=getConfig&p=api',
method: 'GET',
success: function(res) {
app.globalData.categoryId = res.data.data.id;
that.login()
}
})
}
});
// 获取用户信息
wx.getSetting({
success: res => {
var that = this;
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
app.globalData.userInfo = res.userInfo;
app.globalData.iv = res.iv;
app.globalData.encryptedData = res.encryptedData;
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况encryptedData)
if (that.userInfoReadyCallback) {
that.userInfoReadyCallback(res)
}
}
})
}
}
})
},
授权情况下:
控制台输出结果
我自己画的流程图
流程图分析:
首先触发app.onLaunch函数,依次执行内部代码行,在运行到wx.getSetting函数时,由于是个异步,等待结果返回,但程序继续走,进行到index的onLoad函数,app.globalData.userInfo为null,所以进入第二个条件的代码块,并且定义了app.userInfoReadyCallback函数,然后进行到index.onShow,此时app.js中的getSetting数据返回,因为已经授权,继续wx.getUserInfo函数,userInfoReadyCallback为真,执行userInfoReadyCallback函数
未授权情况下:
控制台输出:
自己画的流程图
流程图分析:
首先触发app.onLaunch函数,依次执行内部代码行,在运行到wx.getSetting函数时,由于是个异步,等待结果返回,但程序继续走,进行到index的onLoad函数,app.globalData.userInfo为null,所以进入第二个条件的代码块,并且定义了app.userInfoReadyCallback函数,然后进行到index.onShow,此时app.js中的getSetting数据返回,因为未授权,wx.getUserInfo函数不执行,所以回调函数也不执行,只能人为点击授权,执行index页面的getUserInfo函数