1. 程式人生 > >微信小程式的userInfoReadyCallback相關解釋

微信小程式的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.userInfouserInfo進行賦值,所以當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】