评论

小程序使用 Promise 完成文件异步上传

小程序文件上传方式优化

小程序使用 Promise 完成文件异步上传

extends [微信小程序开发技巧总结(二) – 文件的选取、移动、上传和下载 - Kindear - 博客园 (cnblogs.com)]

在上述文章中我们提到了两种文件上传的方式:

  1. 使用for循环遍历

    优点:接近并发上传,上传速度较快

    缺点:无法保证返回结果的顺序

  2. 采用递归方式上传

    优点:保证了文件的返回顺序和上传顺序一致,且对服务器负载更小

    缺点:由于同步顺序执行上传过程,耗费时间过长

那么有没有一种方式可以让上传异步执行并且保证返回的顺序呢?

鱼与熊掌可以兼得,这波啊,这波不亏

这就引入本篇文章的主角 Promse.all异步并行机制了

关于Promise的两种机制,我就不再赘述,请看参考文档

项目结构

|--upload
     |--upload.js
     |--upload.json
     |--upload.wxml
     |--upload.wxss
     |--profunc.js

本文以云开发图片上传举例

代码展示

profunc.js

const cloudpath = 'baseimg';
function CloudUploadImage(path) {
  // 本地文件路径
  return new Promise(function (resolve, reject) {
    wx.getFileInfo({
      filePath: path,
      success(ans) {
        wx.cloud.uploadFile({
          cloudPath: cloudpath + '/' + ans.digest + '.png',
          filePath: path,
          success: res => {
            resolve(res)
          },
          fail(res) {
            reject('upload fail')
          }
        })
      }
    })
  })
}
module.exports={
  CloudUploadImage:CloudUploadImage
}

upload.js

// pages/upload/upload.js
const cwx = require('profunc.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    imgList:[]
  },
  UploadImage(){
    let imglist = this.data.imgList;
    var promisetasks = []
    for(var i=0;i<imglist.length;i++){
      promisetasks.push(cwx.CloudUploadImage(imglist[i]))
    }
    wx.showLoading({
      title:'图片上传中'
    })
    Promise.all(promisetasks).then(res=>{
      
      console.log(res)
      //具体处理写在如下
    })
  },
  ChooseImage() {
    wx.chooseImage({
      count: 4, //默认9
      sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album'], //从相册选择
      success: (res) => {
        if (this.data.imgList.length != 0) {
          this.setData({
            imgList: this.data.imgList.concat(res.tempFilePaths)
          })
        } else {
          this.setData({
            imgList: res.tempFilePaths
          })
        }
      }
    });
  },
  ViewImage(e) {
    wx.previewImage({
      urls: this.data.imgList,
      current: e.currentTarget.dataset.url
    });
  },
  DelImg(e) {
    this.data.imgList.splice(e.currentTarget.dataset.index, 1);
    this.setData({
      imgList: this.data.imgList
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

upload.wxml

<view class="cu-bar bg-white margin-top">
		<view class="action">
			图片上传
		</view>
		<view class="action">
			{{imgList.length}}/4
		</view>
	</view>
	<view class="cu-form-group">
		<view class="grid col-4 grid-square flex-sub">
			<view class="bg-img" wx:for="{{imgList}}" wx:key="index" bindtap="ViewImage" data-url="{{imgList[index]}}">
				<image src='{{imgList[index]}}' mode='aspectFill'></image>
				<view class="cu-tag bg-red" catchtap="DelImg" data-index="{{index}}">
					<text class="cuIcon-close"></text>
				</view>
			</view>
			<view class="solids" bindtap="ChooseImage" wx:if="{{imgList.length<4}}">
				<text class="cuIcon-cameraadd"></text>
			</view>
		</view>
	</view>

  <view class="padding flex flex-direction">
  <button class="cu-btn bg-green lg" bindtap="UploadImage">上传</button>
  <!-- <button class="cu-btn bg-red margin-tb-sm lg">嫣红</button> -->
</view>

upload.wxss

使用了colorui样式组件,请参考参考文档下载

/* pages/upload/upload.wxss */
@import '/colorui/main.wxss';

参考文档

1. Color Ui | 极其鲜亮的高饱和色彩,更注重视觉的小程序组件库 (color-ui.com)

2.理解和使用Promise.all和Promise.race - 简书 (jianshu.com)

点赞 2
收藏
评论
登录 后发表内容