微信小程序多图片上传实用代码记录
微信小程序多图片上传实用代码记录
由于在小程序中,wx.uploadFile 只能一次上传一张图片,因此在一次需要上传多张图片的应用场景中例如商品图片上传、评论图片上传等场景下,不得不使用for等循环上传每一张图片,多次调用wx.uploadFile,由此引发了ajax的闭包问题。
初始代码
submit() {let tmparr = null;let _that = this;for (var k = 0; k < this.data.judgedetaillist.length; k++) {let _k = k;//图片上传this.data.fileList[_k].forEach((item) => { wx.uploadFile({ //这里一定要用 wx.uploadFile 否则无法穿到后台filePath: item.url, //你要上传的路径name: 'file', //你上传到后台的name值async: false, //设置为同步formData:{ // 如果你要验证你的token 可以用formData来给后台传值path:"judge"},url: 上传地址,success(res){let img = JSON.parse(res.data); //录入到listif(img.err=='success' && img.c_url!=null && img.c_url!=undefined){if(_that.data.judgedetaillist[_k].fileList.length==0 || _that.data.judgedetaillist[_k].fileList==null || _that.data.judgedetaillist[_k].fileList==undefined){_that.data.judgedetaillist[_k].fileList=[];}_that.data.judgedetaillist[_k].fileList.push({url:img.c_url});_that.setData({judgedetaillist:_that.data.judgedetaillist})}}})})}console.log(JSON.stringify(this.data.judgedetaillist));return false;}
代码问题
我这代码的设想是,
遍历储存上传文件的 fileList数组-》wx.uploadFile上传到服务器-》返回服务器路径-》将返回的路径传送到 judgedetaillist.fileList中-》judgedetaillist传输到后台新增评论
这个代码执行下来会出现问题,即在 wx.uploadFile后获取了对应的url存储到judgedetaillist中后
console.log(JSON.stringify(this.data.judgedetaillist));
会出现
fileList":[]
但是
如果打印
console.log(this.data.judgedetaillist);
会出现
fileList: Array(1)
0:
url: “/upload/judge/16654684.png”
proto: Object
length: 1
nv_length: (…)
proto: Array(0)
在预设的对象中又能读取到数据,此时再打印
console.log(this.data.judgedetaillist[0].fileList.length);
发现明明数组中有对象,但是这个对象根本取不到,并且连length都无法读取
原因剖析
由于wx.uploadFile默认是使用异步,因此在不断的for循环中,它返回的值并不是同步的,导致多个同时执行,此时数组使用的是地址引用,并没有实际赋值成功,赋值的数组已经被修改了,因为原来的长度是0,所以获取不到数组,但又包含修改后的结果。
要解决这个bug就是让wx.uploadFile可以同步执行,需要用到
1、new Promise
2、async,await
3、取消forEach, forEach 中使用 async/await 时,异步操作并不会等待前一个操作结束再执行下一个,而是会同时执行多个异步操作
解决方案(非生产环境代码)
本来h5中的多图片上传是直接使用 async:false就可以,但是在微信中这是无效的。所以代码写成这样
解决方案一
使用new Promise,配合async,await进行多次循环
//图片上传函数
Upload: function (uploadFile) {return new Promise((resolve, reject) => {wx.uploadFile({ //这里一定要用 wx.uploadFile 否则无法穿到后台filePath: uploadFile, //你要上传的路径name: 'file', //你上传到后台的name值formData: { // 如果你要验证你的token 可以用formData来给后台传值path: "judge"},url: 上传路径,success: (res) => {// 上传完成操作const data = JSON.parse(res.data)resolve({data: data})},fail: (err) => {//上传失败:修改pedding为rejectwx.showToast({title: "网络出错,上传失败",icon: 'none',duration: 1000});reject(err)}});})},//接收返回的路径,关键是async ,await
async submit() {let tmparr = null;for (var k = 0; k < this.data.judgedetaillist.length; k++) {let _k = k;//图片上传for (let i = 0; i < this.data.fileList[_k].length; i++) {tmparr =await this.Upload(this.data.fileList[_k][i].url);if(this.data.judgedetaillist[_k].fileList==null || this.data.judgedetaillist[_k].fileList==undefined){this.data.judgedetaillist[_k].fileList=[];}this.data.judgedetaillist[_k].fileList.push({ url: tmparr.data.c_url });this.setData({judgedetaillist: this.data.judgedetaillist})}}console.log(JSON.stringify(this.data.judgedetaillist));
}
解决方案二
利用Promise.all,当所有的异步请求成功后才会执行,将全部异步执行完后的数据一次性返回
调用测试
console.log(this.uploadImage(this.data.fileList[_k]))
返回结果
Promise {}
proto: Promise
[[PromiseState]]: “fulfilled”
[[PromiseResult]]: Array(3)
0: “/upload/judge/1691391628202skmda.png”
1: “/upload/judge/1691391628219ttxps.png”
2: “/upload/judge/1691391628227yehwf.png”
length: 3
nv_length: (…)
proto: Array(0)
利用这个可以一次性获取全部的结果
代码示例:
uploadImage: function(tempFilePaths){return new Promise((presolve,preject)=>{if({}.toString.call(tempFilePaths)!='[object Array]'){throw new TypeError(`上传图片参数 tempFilePaths 类型错误!`)}//路径数组为空时 不上传if(tempFilePaths.length==0){presolve([])return}let uploads = []tempFilePaths.forEach((item,i)=>{uploads[i] = new Promise ((resolve)=>{console.log(item);wx.uploadFile({ //这里一定要用 wx.uploadFile 否则无法穿到后台filePath: item.url, //你要上传的路径name: 'file', //你上传到后台的name值formData: { // 如果你要验证你的token 可以用formData来给后台传值path: "judge"},url: 你的上传路径,success(res){console.log(res);resolve(JSON.parse(res.data).c_url)},fail(err){console.log(err)}})})})Promise.all(uploads).then(res=>{//图片上传完成presolve(res)}).catch(err=>{preject(err)wx.showToast({title:'上传失败请重试',icon:'none'})})})},
相关文章:
微信小程序多图片上传实用代码记录
微信小程序多图片上传实用代码记录 由于在小程序中,wx.uploadFile 只能一次上传一张图片,因此在一次需要上传多张图片的应用场景中例如商品图片上传、评论图片上传等场景下,不得不使用for等循环上传每一张图片,多次调用wx.upload…...
android实现获取系统全局对象实例
无需Context获取系统常用全局对象:Application,Activity,PackageManager等。 import android.app.Activity; import android.app.Application; import android.app.Service; import android.content.Context; import android.content.pm.Pac…...
viewerjs 如何新增下载图片功能(npm包补丁)
文章目录 先实现正常的效果实现下载图片改变viewerjs的build函数源码改变之后,执行npm i 之后node_modules源码又变回了原样 1、viwerjs所有功能都很完善,但唯独缺少了图片的下载 2、需求:在用viwerjs旋转图片后,可以直接下载旋转…...
基于YOLOv7开发构建MSTAR雷达影像目标检测系统
MSTAR(Moving and Stationary Target Acquisition and Recognition)数据集是一个基于合成孔径雷达(Synthetic Aperture Radar,SAR)图像的目标检测和识别数据集。它是针对目标检测、机器学习和模式识别算法的研究和评估…...
关于c++中mutable、const、volatile这三个关键字及对应c++与汇编示例源码
这哥三之间的关系是有趣的,不妨看看这个: cv (const and volatile) type qualifiers - cppreference.com mutable permits modification of the class member declared mutable even if the containing object is declared const. 即便一个对象是con…...
把大模型装进手机,分几步?
点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机,AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代,华为盘古大模型将会来助力鸿蒙生态。”8月4日,华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍,…...
c++游戏制作指南(三):c++剧情类文字游戏的制作
🍿*★,*:.☆( ̄▽ ̄)/$:*.★* 🍿 🍟欢迎来到静渊隐者的csdn博文,本文是c游戏制作指南的一部🍟 🍕更多文章请点击下方链接🍕 🍨 c游戏制作指南dz…...
Flutter系列文章-实战项目
在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息,并将用户查询的城市列表保存到本地…...
HCIA---TCP/UDP协议
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一.UDP协议简介 UDP协议的特点: 二.TCP协议简介 TCP协议特点 三.TCP和UDP的区别 思维导图 一.UDP协议简介 UDP(User …...
数据库索引的使用
1、MySQL的基本架构 架构图 左边的client可以看成是客户端,客户端有很多,像我们经常你使用的CMD黑窗口,像我们经常用于学习的WorkBench,像企业经常使用的Navicat工具,它们都是一个客户端。右边的这一大堆都可以看成是…...
校验 GPT-4 真实性的三个经典问题:快速区分 GPT-3.5 与 GPT-4,并提供免费测试网站
现在已经有很多 ChatGPT 的套壳网站,以下分享验明 GPT-4 真身的三个经典问题,帮助你快速区分套壳网站背后到底用的是 GPT-3.5 还是 GPT-4。 大家可以在这个网站测试:https://ai.hxkj.vip,免登录可以问三条,登录之后无限…...
SpringBoot整合MongoDB连接池(含源码)
💡版本依赖 jdk 17 SpringBoot 3.1.0 Mongo 6.0.8 mybatis-plus 2.0.2 💡环境准备 🌵MongoDB安装 安装教程请查看:一文搞定(linuxwindowsdocker)安装MongoDB 🌵导入依赖 <parent><groupId>org.sp…...
[oeasy]python0082_[趣味拓展]控制序列_清屏_控制输出位置_2J
光标位置 回忆上次内容 上次了解了键盘演化的过程 ESC 从 组合键到 独立按键 ESC的作用 是 进入 控制序列配置 控制信息控制信息 \033[y;xH 设置光标位置\033[2J 清屏 这到底怎么控制???🤔谁来实现这些功能? 控制…...
Zookeeper+kafka
目录 1. Zookeeper定义 2. Zookeeper工作机制 3. Zookeeper特点 4. Zookeeper数据结构 5. Zookeeper应用场景 5.1 统一命名服务 5.2 统一配置管理 5.3 统一集群管理 5.4 服务器动态上下线 5.5 软负载均衡 6. Zookeeper 选举机制 6.1 第一次启动选举机制 6.2 非第一…...
Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基础页面框架的静态设计(二)
Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基础页面框架的静态设计(二) 在开始这个专栏,我们需要找一个小程序为参考,参考和仿照其界面,聊天交互模式。 这里参考小程序-小柠AI智能聊天,可自行先体验。 该小程序主要提供了…...
Flask进阶:构建RESTful API和数据库交互
在初级教程中,我们已经介绍了如何使用Flask构建基础的Web应用。在本篇中级教程中,我们将学习如何用Flask构建RESTful API,以及如何使用Flask-SQLAlchemy进行数据库操作。 一、构建RESTful API REST(Representational State Tran…...
6.9(Java)二叉搜索树
1.我的代码: public class BinarySearchTree {class TreeNode {public int key;public TreeNode left;public TreeNode right;public TreeNode(int key) {this.key key;}}public TreeNode root; // 根节点// 插入一个元素,注意,不能插入重复的值,如…...
洛谷P2256 一中校运会之百米跑
题目背景 在一大堆秀恩爱的 ** 之中,来不及秀恩爱的苏大学神踏着坚定(?)的步伐走向了 100 100 100 米跑的起点。这时苏大学神发现,百米赛跑的参赛同学实在是太多了,连体育老师也忙不过来。这时体育老师发…...
python-opencv对极几何 StereoRectify
OpenCV如何正确使用stereoRectify函数 函数介绍 用于双目相机的立体校正环节中,这里只谈谈这个函数怎么使用,参数具体指哪些函数参数 随便去网上一搜或者看官方手册就能得到参数信息,但是!!相对关系非常容易出错&…...
pom文件---maven
027-Maven 命令行-实验四-生成 Web 工程-执行生成_ev_哔哩哔哩_bilibili 27节.后续补充 一.maven下载安装及配置 1)maven下载 2) settings文件配置本地仓库 3)settings配置远程仓库地址 4)配置maven工程的基础JDK版本 5)确认JDK环境变量配置没问题,配置maven的环境变量 验证…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
