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:以上只是自己的想法和推测,希望路过的大神能多多指正!  

  • 相关阅读:
    小程序与VUE请求后台接口,传数组
    VUE中使用Echarts图表
    封装一个VUE时间线组件
    Git的使用方法及IDEA与Git的集成(二)
    Git中拥有不同的仓库的不同账户
    IDEA无法集成Git问题
    IDEA之debug学习
    MyBatis 学习(三)
    MyBatis 学习(二)
    MyBatis 学习(一)
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/9338404.html
Copyright © 2011-2022 走看看