首先,上代码片段
release(e){ var imageUrl = []; var temp = []; for ( var i = 0; i < this .data.filepath.length; i++) { wx.cloud.uploadFile({ cloudPath: this .data.cloudpath[i], // 上传至云端的路径 filePath: this .data.filepath[i], // 小程序临时文件路径 success: res => { imageUrl = imageUrl.concat(res.fileID) temp = res.fileID console.log( 'imageUrl' , imageUrl) } }) } console.log( 'imageUrl aaaa' , imageUrl) console.log( 'temp bbbb' , temp) db.collection( 'emall' ).add({ data: { title: this .data.location + '出租' , price: this .data.price + '/月' , image: imageUrl, inDate: this .data.date, pictureCnt: i, }, success: res2 => { console.log( '文件上传成功' , res2) wx.showToast({ title: '新增成功' , }) }, fail: err => { console.error( 'error' , err) } }) }, |
背景介绍:
我有一个商品信息需要上传到数据库,这个商品有多张图片来描述;
在上面的release接口中,有一个for循环,实现上传多张图片到腾讯云,把上传成功的fileid用一个数组记录下来
所有图片上传成功后,将这些腾讯云的图片路径和商品信息保存在一个数据库记录中
遇到的问题
实际调试时,发现程序执行到wx.cloud.uploadFile时,并没有等待这个数据是否上传成功,而是继续向下执行了,因此会发现先打印了
imageUrl aaaa temp bbbb |
然后会接着打印,以及真正的云端路劲地址
imageUrl |
疑惑的地方
在函数release中调用wx.cloud.uploadFile的时候,它并不知道什么时候上传成功,就会直接跳转到后面的函数执行,那有什么办法能够确认wx.cloud.uploadFile函数执行成功后再继续执行release函数后面的语句吗?
因为我是嵌入式C语言出生,小程序以及js语言完全属于自学,这样的用法感觉好奇怪,一个函数里面像是发生了线程调度,被打断后,继续执行这个函数后面的操作,这是什么逻辑操作?还是很多前端部分的语言都是这个德行?按照C语言的执行流程,这个时候release函数就应该block在这边,等待wx.cloud.uploadFile执行完成之后,再继续执行;或者你也可以引发一次线程调度,执行其他的部分,但是release函数肯定是被block住的。
等图片上传成功后,又返回到wx.cloud.uploadFile的success中继续执行,可是给我感觉在图片上传成功之前,release整个函数都应该执行结束了,然后微信小程序还会继续自行跳转到这个函数中来执行,这个又是什么神操作?那么release这个函数的生命周期究竟是多少?
难怪之前在网上看到有人用了递归的方法来做wx.cloud.uploadFile,当时还没完全理解别人这样做的意义何在,今天调试下来感觉应该就是现在反馈的问题带来的处理,可是循环比递归理解起来简单多了呀
经过调试之后,现在想到了一个解决策略,等待多张图片都存放到腾讯云之后,再将这些图片的云存储路径存放到的数据库中,代码如下
release(e){
//console.log('I am here', e)
var
imageUrl = [];
var
temp = [];
var
uploadSuccessCnt = 0;
for
(
var
i = 0; i <
this
.data.filepath.length; i++) {
wx.cloud.uploadFile({
cloudPath:
this
.data.cloudpath[i],
// 上传至云端的路径
filePath:
this
.data.filepath[i],
// 小程序临时文件路径
success: res => {
//console.log('I am here', res)
imageUrl = imageUrl.concat(res.fileID)
temp = res.fileID
//console.log('imageUrl', imageUrl)
uploadSuccessCnt++;
//console.log('uploadSuccessCnt', uploadSuccessCnt)
if
(uploadSuccessCnt == i){
db.collection(
'emall'
).add({
data: {
title:
this
.data.location +
'出租'
,
price:
this
.data.price +
'/月'
,
image: imageUrl,
inDate:
this
.data.date,
pictureCnt: i,
},
success: res2 => {
console.log(
'文件上传成功'
, res2)
wx.showToast({
title:
'新增成功'
,
})
},
fail: err => {
console.error(
'error'
, err)
}
})
}
}
})
}
},
但是帖子中的几个疑惑的地方还是不是很明白
虽然不是和理解,但照这个方法解决了问题,很感谢
可算tm解决了。用了你 计数的方法。uploadSuccessCnt++; 太感谢你了,就这一个问题。我坐这儿两天了,头都要炸了。我真看不懂那些 递归的什么鬼。 异步那个好像很有道理,但本人脑子不好使,还是你这个实惠方便。
我也研究过,wx.cloud.uploadFile,可以读取外部的变量,并且在函数内部继续变化,但最终的值是不能传个函数外部的。
/**上传照片到云端 */
confirmUpload: function() {
var temp = this.data.tempFilePaths
var length = temp.length
var upLoadCount1 = 0
for (let i = 0; i < length; i++) {
// 上传图片
const filePath = this.data.tempFilePaths[i]
const cloudPath = 'my' + i.toString() + filePath.match(/\.[^.]+?$/)
//云端调用,引用的外部变量的值不能回传给外部
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
console.log('[上传文件] 成功:i=', i, res)
upLoadCount1++
//比较计数器和准备上传的照片数,
if (upLoadCount1==length){
wx.showToast({
title: upLoadCount1.toString() + '个照片传成功!'
})
}
},
fail: e => {
console.error('[上传文件] 失败:', e)
wx.showToast({
icon: 'none',
title: '上传失败',
})
},
complete: () => {
}
})
}
},
异步的原因,改成同步就没毛病了。
理解一下异步。上传是异步操作,这一部分代码执行后异步上传还在进行中,但是代码会往下面执行。success 回调被调用时后面代码都已经执行完了。