微信小程式的userInfoReadyCallback相關解釋
關於微信小程式quickstart專案中的userInfoReadyCallback,大體可以總結以下三點:
1.userInfoReadyCallback這個方法是在page.onload中定義的。
2.如果userInfoReadyCallback方法被定義了,則說明page.onload比當前方法執行的早(page已經完成初始化),app的globalData還沒有資料,通過此回撥可以及時的重新整理資料
3.如果userInfoReadyCallback方法沒有被定義,則說明page.onload比當前方法執行的晚(page還沒有初始化),app的globalData是有值的,可以在page.onload中取globalData裡面的值
以上是百度搜索到的答案。
下面是個人的見解:
app.js
// 獲取使用者資訊 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框 wx.getUserInfo({ success: res => { // 可以將 res 傳送給後臺解碼出 unionId that.globalData.userInfo = res.userInfo // 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回 // 所以此處加入 callback 以防止這種情況 console.log('app1'); if (that.userInfoReadyCallback) { console.log('app2'); that.userInfoReadyCallback(res) } }, 3000); } }) } } })
index.js
onLoad: function () { if (app.globalData.userInfo) { console.log('page1'); this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse){ console.log('page2'); // 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回 // 所以此處加入 callback 以防止這種情況 // 給app.js 定義一個方法。 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 在沒有 open-type=getUserInfo 版本的相容處理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } }
講解之前先明確兩點:
1.app.js的wx.getSetting是在onLaunch裡面執行的
2.執行順序:app.onLaunch--->page.onLoad
通過上面程式碼,可見我在app.js和index.js檔案設定了幾個輸出,以便觀察程式碼執行順序,以下是執行結果:圖1-1
進入小程式,首先執行app.onLaunch,接著執行wx.getSetting中的wx.getUserInfo,由於wx.getUserInfo是非同步執行的,所以在這裡可以分為兩種情況。
a.在page.onLoad執行之前,wx.getUserInfo已經執行完畢,通過success方法中的that.globalData.userInfo = res.userInfo為userInfo進行賦值,所以當page.onLoad執行判斷app.globalData.userInfo的時候,app.globalData.userInfo是有值的,所以輸出會【page1】
b.在wx.getUserInfo還沒執行完成的時候,也就是還沒回調success時,程式碼仍舊會往下執行。
這時app.onLaunch執行完畢後,會輪到page.onLoad執行。在判斷app.globalData.userInfo時,由於app.globalData.userInfo因為wx.getUserInfo還未執行完成,所以沒有值,所以會走另一個判斷,因此輸出了【page2】。
之後,我們可以看到app.userInfoReadyCallback = res =>{},這是在為app.js定義一個userInfoReadyCallback方法,以便wx.getUserInfo成功執行後,能夠賦值給userInfo。當page.onLoad執行完畢之後,此時wx.getUserInfo執行success,會先判斷app.userInfoReadyCallback是否被定義,若被定義了則執行這個方法,達到為userInfo進行賦值的目的。
在絕大多數情況下wx.getUserInfo都會先比page.onLoad先執行完成,所以為了達到第二種效果,我們新增一個計時器。
app.js
wx.getUserInfo({
success: res => {
var that = this
setTimeout(function () {
// 可以將 res 傳送給後臺解碼出 unionId
that.globalData.userInfo = res.userInfo
// 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回
// 所以此處加入 callback 以防止這種情況
console.log('app1');
if (that.userInfoReadyCallback) {
console.log('app2');
that.userInfoReadyCallback(res)
}
}, 3000);
}
})
執行結果:可以看到,會先輸出【page2】,然後才是進入到wx.getUserInfo的success方法中,輸出【app1】,接著就是我們所說的執行判斷是否定義userInfoReadyCallback,最後輸出【app2】