初學微信小程序,總是搞不清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)
}
}
})
}
}
})
},
授權情況下:
控制臺輸出結果
image.png
我自己畫的流程圖
image.png
流程圖分析:
首先觸發app.onLaunch函數,依次執行內部代碼行,在運行到wx.getSetting函數時,由于是個異步,等待結果返回,但程序繼續走,進行到index的onLoad函數,app.globalData.userInfo為null,所以進入第二個條件的代碼塊,并且定義了app.userInfoReadyCallback函數,然后進行到index.onShow,此時app.js中的getSetting數據返回,因為已經授權,繼續wx.getUserInfo函數,userInfoReadyCallback為真,執行userInfoReadyCallback函數
未授權情況下:
控制臺輸出:
image.png
自己畫的流程圖
image.png
流程圖分析:
首先觸發app.onLaunch函數,依次執行內部代碼行,在運行到wx.getSetting函數時,由于是個異步,等待結果返回,但程序繼續走,進行到index的onLoad函數,app.globalData.userInfo為null,所以進入第二個條件的代碼塊,并且定義了app.userInfoReadyCallback函數,然后進行到index.onShow,此時app.js中的getSetting數據返回,因為未授權,wx.getUserInfo函數不執行,所以回調函數也不執行,只能人為點擊授權,執行index頁面的getUserInfo函數