zoukankan      html  css  js  c++  java
  • 小程序中生命周期钩子函数之外的全局变量要小心使用!!!

    之前做的上传水印这块的功能。

    有时候由于网络过慢,重复点击的话可能会导致重复打包(生成照片包)。本身做法可以在请求的过程中可以让button禁用,这个就不多讨论。

    我当时临时采用的是利用一个变量来控制,请求发出前把变量全局变量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呢?

    原因分析:小程序考虑到内存问题的情况下,所以在不同的路由情况会卸载路由前的页面,以缓解内存压力,但是可能这种不是完全的释放内存,Unload卸载的是page对象内的一系列东西,包含data以及钩子函数。

      但是由于isSaving是写在page外面的全局变量,还是存在于微信缓存中的,所以页面卸载后再重新加载,它的值始终是没有重置的。

    以下是isSaving的写法:

    另外重新试了下,var声明的isSaving 只是相对于组件的全局变量,我在打包成功后的跳转到的消息页page中打印是以下结果:

    总结:对于自己的的没有处理好数据导致的小Bug,对小程序的人认识又增进一步真的是喜忧参半。大家对于小程序的page钩子函数,页面unload的理解要多注意,分辨出page之外定义的伪全局变量带来的影响。

    追述:小程序page函数,app对象之外的变量类似为顶级变量。需要小程序退出(后台5分钟或者内存超标)才会注销。根据小程序的模块化概念可以单独抽离出js文件,再结合生命周期概念,小程序中定义的页面这一概念来配合对应的onload,onshow,unload等钩子,针对的是page整个对象,所以即使这个a变量和page函数是写在一个wx.j文件里,但我们不能就看成是绑定在一起的整体,事实上页面的卸载是执行的清理掉对应的page对象,而不是释放整个js文件。所以a的值会始终保持一个状态!

    ps:以上只是自己的想法和推测,希望路过的大神能多多指正!  

  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/9338404.html
Copyright © 2011-2022 走看看