之前做的上传水印这块的功能。
有时候由于网络过慢,重复点击的话可能会导致重复打包(生成照片包)。本身做法可以在请求的过程中可以让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:以上只是自己的想法和推测,希望路过的大神能多多指正!