小程序中生命週期鉤子函數以外的全局變量要當心使用!!!

以前作的上傳水印這塊的功能。javascript

有時候因爲網絡過慢,重複點擊的話可能會致使重複打包(生成照片包)。自己作法能夠在請求的過程當中可讓button禁用,這個就很少討論。java

我當時臨時採用的是利用一個變量來控制,請求發出前把變量全局變量isSaving變成true,而後再按鈕的點擊事件剛進來的時候判讀,若是isSaving是true的話那麼就return。小程序

saveAndShare(){
    if(isSaving){
      return
    }
    let files = this.data.files;
    let _this = this;
    if(files.length == 0){
      wx.showModal({
        content: '請上傳照片!',
        showCancel: false,
        success: function (res) {
          if (res.confirm) {
            _this.chooseImage()
          }
        }
      })
      return
    }
    if(!this.data.title){
      wx.showModal({
        content: '請填寫標題',
        showCancel: false,
        success: function (res) {
          _this.setData({
            titleFocus:true
          })
        }
      })
      return
    }
    //驗證是否是上傳圖片後面時才加的水印,這裏須要從新攔截處理
    //無需考慮複雜操做,只考慮同款水印,要麼都有,要麼沒有。

    //第一步:驗證圖片路徑有沒有水印信息。
    if (!files[0].includes('x-oss-process') && _this.data.encodeWord){
      console.log('執行')
      for(let i = 0;i<files.length;i++){
        files[i] += '?' + _this.data.urlHead + _this.data.encodeWord + _this.data.urlFoot;
      }
    }
    let uid = wx.getStorageSync('id');
    let contentList = [];
    let creator = null;
    for(let i = 0;i < files.length;i++){
      contentList.push({
        sequence:i,
        path: files[i].replace(_this.data.host,'')
      })
    }
    if (app.globalData.userInfo){
      creator = app.globalData.userInfo.nickName;
    }
    isSaving = true
    wx.request({
      url: util.head+'/mp/pr/img/package',
      method: 'POST',
      data: {
        uid,
        watermark: _this.data.word,
        title: _this.data.title,
        notes: _this.data.note,
        creator,
        contentList,
        contentNum: _this.data.files.length
      },
      success: function (res) {
        console.log(res.data)
        if (res.data.status == 'SUCCESS'){
          let id  = res.data.data;
          let creator = app.globalData.userInfo.nickName;
          let face = _this.data.files[0].split('?')[0];
          let title = _this.data.title
          wx.showToast({
            title: '打包成功',
            icon: 'success',
            duration: 1000,
            success: function () {
              setTimeout(function () {
                wx.reLaunch({
                  url: `/pages/msg/msg?id=${id}&creator=${creator}&face=${face}&title=${title}`,
                })
              }, 800)
            }
          })
        }else{
          isSaving = false;
          wx.showToast({
            title: '打包失敗',
            icon: 'none',
            duration: 1000
          })
        }
      }
    })
  },
  /**

其實這裏個人漏洞是打包成功後應該把變量還原的。可是考慮到成功後會relauch跳轉到消息頁。緩存

根據官方的路由說明,重啓動路由方式執行後,當前的這個上傳頁面會unload掉。微信

包括我進入了消息頁以後(消息頁是非Tab頁),而後用switchTab進入了列表頁(第二個tab選項),再從新切到第一個tab選項,再點擊navigate進入回到上傳頁面,一系列操做後,網絡

講道理頁面第一步的時候已經卸載掉了,從新進入也是執行onload的,可是爲何isSaving仍是true呢?app

緣由分析:小程序考慮到內存問題的狀況下,因此在不一樣的路由狀況會卸載路由前的頁面,以緩解內存壓力,可是可能這種不是徹底的釋放內存,Unload卸載的是page對象內的一系列東西,包含data以及鉤子函數。模塊化

  可是因爲isSaving是寫在page外面的全局變量,仍是存在於微信緩存中的,因此頁面卸載後再從新加載,它的值始終是沒有重置的。函數

如下是isSaving的寫法:ui

另外從新試了下,var聲明的isSaving 只是相對於組件的全局變量,我在打包成功後的跳轉到的消息頁page中打印是如下結果:

 

總結:對於本身的的沒有處理好數據致使的小Bug,對小程序的人認識又增進一步真的是喜憂參半。你們對於小程序的page鉤子函數,頁面unload的理解要多注意,分辨出page以外定義的僞全局變量帶來的影響。

追述:小程序page函數,app對象以外的變量相似爲頂級變量。須要小程序退出(後臺5分鐘或者內存超標)纔會註銷。根據小程序的模塊化概念能夠單獨抽離出js文件,再結合生命週期概念,小程序中定義的頁面這一律念來配合對應的onload,onshow,unload等鉤子,針對的是page整個對象,因此即便這個a變量和page函數是寫在一個wx.j文件裏,但咱們不能就當作是綁定在一塊兒的總體,事實上頁面的卸載是執行的清理掉對應的page對象,而不是釋放整個js文件。因此a的值會始終保持一個狀態!

ps:以上只是本身的想法和推測,但願路過的大神能多多指正!  

相關文章
相關標籤/搜索