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