微信小程序promsie.all和promise顺序执行


Posted in Javascript onOctober 27, 2017

微信小程序promsie.all和promise顺序执行

一、前言

最近在做小程序的开发,碰到的一个需求就是表单提交,提交的表单中包含有图片,微信这边的做法是先上传图片,后台把图片名称和地址返回给你,然后你把图片信息插入到表单的相应位置再提交表单,这里就涉及到如何上传完图片的请求再上传表单,而且微信小程序里面如果图片是多个的话,也只能一张张上传。简单来说就是上传完图片(多个请求),拿到返回值,再上传表单,该如何做?

二、Promise.all和Promise.race

先来介绍Promise.all和Promise.race方法的不同点Promise.all(iterable) 方法指当所有在可迭代参数中的 promises 已完成,或者第一个传递的 promise(指 reject)失败时,返回 promise。iterable为可迭代对象,但是一般为数组。返回值也是一个Promise对象。

需要明确的几点,Promise.all是并发执行的同时运行多个Promise对象,而且返回的Promise对象的参数是一个数组,数组中的各项也是可迭代对象执行的顺序返回。

Promise.race(iterable) 方法返回一个新的 promise,参数iterable中只要有一个promise对象”完成(resolve)”或”失败(reject)”,新的promise就会立刻”完成(resolve)”或者”失败(reject)”,并获得之前那个promise对象的返回值或者错误原因。所以只要iterable中有一个完成或者失败就立即返回一个promise对象。根据race这个单词为赛跑也能得出,最先到达的立即返回一个promise对象。

根据上面的定义,我们采用的Promise.all方法来完成我们的需求。

//存储promise对象的数组
let promiseArr = [];
//图片地址数组
let imageList = [];
//将图片地址的上传的promise对象加入到promiseArr
for (let i = 0; i < imageList.length; i++) {
  let promise = new Promise((resolve, reject) => {
    //微信图片上传
    wx.uploadFile({
      url: 'https://xxx.xxx.xxx/api/uploadImage',
      filePath: imageList[i],
      name: 'file',
      success: function(res) {
        //可以对res进行处理,然后resolve返回
        resolve(res);
      },
      fail: function (error) {
        reject(error);
      },
      complete: function (res) {
      },
    })
  });
  promiseArr.push(promise)
}
//Promise.all处理promiseArr数组中的每一个promise对象
Promise.all(promiseArr).then((result) => {
  //对返回的result数组进行处理
})

三、微信小程序的问题

在做微信小程序的图片上传功能,这边只能先上传图片,然后将图片名和地址以response返回。

这里面我们就是用了promise.all方法但是有一个问题就是,promise.all是并发执行的,但是微信小程序一次只能并发10个请求。

对于图片上传,可能需要一次上传超过10张图片,也就是一次并发超过10个请求,这样的话微信就会报错

“WAService.js:4 uploadFile:fail createUploadTask:fail exceed max upload connection count 10”。

微信小程序promsie.all和promise顺序执行

四、顺序Promise执行处理

因为Promise.all是同时运行多个promsie对象,所以对于这种并发的数量,小程序是有限制的,一次只能并发10个,所以如果想突破这种限制,可以进行顺序执行每个Promise。

代码如下:

//顺序处理函数
function sequenceTasks(tasks) {
  //记录返回值
  function recordValue(results, value) {
    results.push(value);
    return results;
  }
  let pushValue = recordValue.bind(null, []);
  let promise = Promise.resolve();
  // 处理tasks数组中的每个函数对象
  for (let i = 0; i < tasks.length; i++) {
    let task = tasks[i];
    promise = promise.then(task).then(pushValue);
  }
  return promise;
}

//函数数组,每个函数的返回值是一个promise对象
let promiseFuncArr = [];
//图片地址数组
let imageList = [];
//将图片地址的上传的函数加入到promiseFuncArr数组中
for (let i = 0; i < imageList.length; i++) {
  let promiseTemp = function(){
    return new Promise((resolve, reject) => {
      //微信图片上传
      wx.uploadFile({
        url: 'https://xxx.xxx.xxx/api/uploadImage',
        filePath: imageList[i],
        name: 'file',
        success: function(res) {
          //可以对res进行处理,然后resolve返回
          resolve(res);
        },
        fail: function (error) {
          reject(error);
        },
        complete: function (res) {
        },
      })
    });
  };
  promiseFuncArr.push(promiseTemp)
}

sequenceTasks(promiseFuncArr).then((result) => {
  //对返回的result数组进行处理
});

1.这里解释一下sequenceTasks函数的作用

首先recordValue函数传入两个值,一个是results是返回的数组,另一个是value,value是传入的值,results.push(value);将每一个值push到results数组,然后再返回results数组。

let pushValue = recordValue.bind(null, []);

pushValue也是一个函数对象,将recordValue bind到一个[ ]数组中,第一个参数传null代表,不改变函数this的指向,所以pushValue得到就是一个function (value)的函数,参数传入value。

promise = promise.then(task).then(pushValue);

task是函数,函数返回promise对象,在我们这里就是上传图片函数,每一张图片上传都创建一个函数,then(pushValue),pushValue是function (value)的函数,value代表的就是图片上传之后的返回值,pushValue将返回值push到result数组中,依次执行,依次加入到result数组中,最后返回。就可以得到一个对象数组,数组中就是依次执行返回的结果。

2. sequenceTasks也里面的for循环,也可以写成如下的reduce方式:

function sequenceTasks(tasks) {
  //记录返回值
  function recordValue(results, value) {
    results.push(value);
    return results;
  }
  let pushValue = recordValue.bind(null, []);
  return tasks.reduce(function (promise, task) {
    return promise.then(task).then(pushValue);
  }, Promise.resolve());
}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
犀利的js 函数集合
Jun 11 Javascript
javascript实现div的拖动并调整大小类似qq空间个性编辑模块
Dec 12 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
Mar 29 Javascript
JS实现下拉框的动态添加(附效果)
Apr 03 Javascript
SwfUpload在IE10上不出现上传按钮的解决方法
Jun 25 Javascript
Javascript 中创建自定义对象的方法汇总
Dec 04 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
Mar 24 Javascript
javascript点击按钮实现隐藏显示切换效果
Feb 03 Javascript
BootStrap+Mybatis框架下实现表单提交数据重复验证
Mar 23 Javascript
原生JavaScript实现Ajax异步请求
Nov 19 Javascript
vue监听键盘事件的快捷方法【推荐】
Jul 11 Javascript
vue click.stop阻止点击事件继续传播的方法
Sep 04 Javascript
JS+CSS实现网页加载中的动画效果
Oct 27 #Javascript
vue-resource拦截器设置头信息的实例
Oct 27 #Javascript
Vue-resource拦截器判断token失效跳转的实例
Oct 27 #Javascript
vue2里面ref的具体使用方法
Oct 27 #Javascript
初学者AngularJS的环境搭建过程
Oct 27 #Javascript
JavaScript中Require调用js的实例分享
Oct 27 #Javascript
JavaScript自执行函数和jQuery扩展方法详解
Oct 27 #jQuery
You might like
一个用于网络的工具函数库
2006/10/09 PHP
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
php利用递归实现删除文件目录的方法
2016/09/23 PHP
彻底搞懂PHP 变量结构体
2017/10/11 PHP
jquery 问答知识整理
2010/02/11 Javascript
Jquery 模拟用户点击超链接或者按钮的方法
2013/10/25 Javascript
jquery禁用右键单击功能屏蔽F5刷新
2014/03/17 Javascript
JS随机洗牌算法之数组随机排序
2016/03/23 Javascript
jQuery实现简单倒计时功能的方法
2016/07/04 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
Vuejs实现带样式的单文件组件新方法
2017/05/02 Javascript
浅谈JavaScript find 方法不支持IE的问题
2017/09/28 Javascript
angularjs数组判断是否含有某个元素的实例
2018/02/27 Javascript
在vue项目中集成graphql(vue-ApolloClient)
2018/09/08 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
2020/09/02 Javascript
jQuery实现朋友圈查看图片
2020/09/11 jQuery
[45:25]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
从零学python系列之教你如何根据图片生成字符画
2014/05/23 Python
利用Fn.py库在Python中进行函数式编程
2015/04/22 Python
python 字典 按key值大小 倒序取值的实例
2018/07/06 Python
使用TensorFlow搭建一个全连接神经网络教程
2020/02/06 Python
python环境下安装opencv库的方法
2020/03/05 Python
python 安装impala包步骤
2020/03/28 Python
教师绩效考核方案
2014/01/21 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
电子商务专业求职信
2014/03/08 职场文书
公司管理建议书范文
2014/03/12 职场文书
百货商场楼层班组长竞聘书
2014/03/31 职场文书
群众路线教育实践活动对照检查材料思想汇报(副处级领导)
2014/10/04 职场文书
安全保证书
2015/01/16 职场文书
经济纠纷起诉状
2015/05/20 职场文书
爱国主义电影观后感
2015/06/18 职场文书
2015秋季开学典礼主持词
2015/07/16 职场文书
mysql分表之后如何平滑上线详解
2021/11/01 MySQL
SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法
2022/07/07 Java/Android
IDEA中sout快捷键无效问题的解决方法
2022/07/23 Java/Android