巧用回调函数解决微信小程序与后台数据交互出现的异步问题

问题描述

        微信小程序端需要发送一个包含文字与图片的表单数据给后端,我一开始的思路是上传图片得到临时的URL,执行POST请求将表单数据发送给后端,但后端只能获取到文字,而图片URL却始终获取不到。

问题原因

        注意看我上面的思路,一先一后,无形中将两个操作进行异步执行了,顾名思义,两个行为分开同时执行,但是二者执行速度却不一致从而导致出错。因为图片的上传执行速度肯定比发送POST请求这一动作要慢一步,因为耗时长,还会受网络速度的影响。所以当后台已经收到小程序端发来的POST请求时,图片上传还未完成,因此URL就是空的,等到图片上传完成了拿到URL了,但此时POST请求早已执行完毕,二者相互错开,异步执行是问题的根本原因。

错误代码

//表单提交事件
        ReportFormData(e){
            wx.showLoading({
                title: '上传中',
              })
            this.setData({
                formdata:e.detail.value
            })
            this.uploadimg()//上传图片获取URL
            //向后端发送POST请求提交表单数据
            wx.request({
                url: 'http://localhost:8081/wx/hd/add',
                method:"POST",
                data:JSON.stringify({
                  "sbr":userid,
                  "yhdd":form.yhdd,
                  "yhbw":form.yhbw,
                  "yhms":form.yhms,
                  "yhzp":[{ "url":res3.fileList[0].tempFileURL}]
                }),
                header:{'content-type': 'application/json'},
                success:res=>{
                    wx.showToast({
                      title: '上传成功',
                    })
                    console.log(res);
                }
              })
        },
        //将用户上传的隐患照片上传到云数据库中进行存储
        uploadimg(){
            wx.cloud.uploadFile({
                //  使用随机生成数来为图片文件命名,极大避免文件名冲突问题
                cloudPath:`${Math.floor(Math.random()*10000000)}.png`,
                filePath:this.data.imgs[0],
                success:res2=>{
                    console.log(res2)
                    //获取图片的临时下载链接
                    wx.cloud.getTempFileURL({
                        fileList:[res2.fileID],
                        success:res3=>{
                            this.setData({
                                filepath:res3.fileList[0].tempFileURL
                            })
                            console.log("获取到的url地址为:",this.data.filepath)
                            wx.hideLoading()
                        }
                    })
                }
            })
            console.log("上传的图片",this.data.imgsfileIDs)
        },

解决方法

        将二者进行同步操作,就是顺序执行,当图片上传完成拿到URL之后再去执行发送POST请求的操作,即后者执行的条件是前者执行完成,这样让后者“等一等”前者,这是解决问题的核心思路。我们这里采用的方法是在上传图片拿到URL后的回调函数中来执行POST请求,这样巧妙地利用了回调函数的特点解决了异步问题。

正确代码

       //表单提交事件
        ReportFormData(e){
            wx.showLoading({
                title: '上传中',
              })
            this.setData({
                formdata:e.detail.value
            })
            this.uploadimg()//上传图片获取URL
        },
         
        //将用户上传的隐患照片上传到云数据库中进行存储
        uploadimg(){
            wx.cloud.uploadFile({
                //  使用随机生成数来为图片文件命名,极大避免文件名冲突问题
                cloudPath:`${Math.floor(Math.random()*10000000)}.png`,
                filePath:this.data.imgs[0],
                success:res2=>{
                    console.log(res2)
                    //获取图片的临时下载链接
                    wx.cloud.getTempFileURL({
                        fileList:[res2.fileID],
                        success:res3=>{
                            let userid=getApp().globalData.userOpenID
                            let form=this.data.formdata
                            //向后端发送POST请求提交表单数据
                            wx.request({
                                url: 'http://localhost:8081/wx/hd/add',
                                method:"POST",
                                data:JSON.stringify({
                                  "sbr":userid,
                                  "yhdd":form.yhdd,
                                  "yhbw":form.yhbw,
                                  "yhms":form.yhms,
                                  "yhzp":[{ "url":res3.fileList[0].tempFileURL}]
                                }),
                                header:{'content-type': 'application/json'},
                                success:res=>{
                                    wx.showToast({
                                      title: '上传成功',
                                    })
                                    console.log(res);
                                }
                              })
                            this.setData({
                                filepath:res3.fileList[0].tempFileURL
                            })
                            console.log("获取到的url地址为:",this.data.filepath)
                            wx.hideLoading()
                        }
                    })
                }
            })
        },

总结

        除非必要时候,否则尽量使用同步方法,即顺序执行程序,避免使用异步方法造成不必要的隐患问题,这样的BUG是由于程序执行速度不一致导致的,并不是代码本身的错误,因此非常非常的难找。

 参考文章

微信小程序同步方法与异步方法对比icon-default.png?t=N0U7https://blog.csdn.net/hxfghgh/article/details/82817943?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167544181616800182143390%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167544181616800182143390&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-82817943-null-null.142^v73^pc_new_rank,201^v4^add_ask,239^v1^control&utm_term=%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5&spm=1018.2226.3001.4187微信小程序(API---简介、运行机制及同步异步)icon-default.png?t=N0U7https://blog.csdn.net/weixin_45343973/article/details/100977882?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-100977882.142^v73^pc_new_rank,201^v4^add_ask,239^v1^control&spm=1018.2226.3001.4187 

道阻且长,多踩坑才能成长!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aricl.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值