微信小程序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 相关文章推荐
真正的JQuery.ajax传递中文参数的解决方法
May 28 Javascript
最常用的12种设计模式小结
Aug 09 Javascript
input输入框的自动匹配(原生代码)
Mar 19 Javascript
jquery实现动态画圆
Dec 04 Javascript
漫谈JS引擎的运行机制 你应该知道什么
Jun 15 Javascript
window.close(); 关闭浏览器窗口js代码的总结介绍
Jul 14 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
Apr 20 Javascript
jquery.validate.js 多个相同name的处理方式
Jul 10 jQuery
Bootstrap 按钮样式与使用代码详解
Dec 09 Javascript
mongodb初始化并使用node.js实现mongodb操作封装方法
Apr 02 Javascript
微信小程序自定义navigationBar顶部导航栏适配所有机型(附完整案例)
Apr 26 Javascript
VUE中V-IF条件判断改变元素的样式操作
Aug 09 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
Apache2 httpd.conf 中文版
2006/12/06 PHP
分享一下贝贝成长进度的php代码
2012/09/14 PHP
浅谈php函数serialize()与unserialize()的使用方法
2014/08/19 PHP
php实现简单的权限管理的示例代码
2017/08/25 PHP
PHP封装XML和JSON格式数据接口操作示例
2019/03/06 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
IE JS编程需注意的内存释放问题
2009/06/23 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
jQuery简单实现图片预加载
2015/04/20 Javascript
jquery mobile 实现自定义confirm确认框效果的简单实例
2016/06/17 Javascript
jQuery基于函数重载实现自定义Alert函数样式的方法
2016/07/27 Javascript
canvas绘制七巧板
2017/02/03 Javascript
简单实现js无缝滚动效果
2017/02/05 Javascript
原生js实现可拖拽效果
2017/02/28 Javascript
使用angular-cli webpack创建多个包的方法
2018/10/16 Javascript
详解vue中使用protobuf踩坑记
2019/05/07 Javascript
Node.JS发送http请求批量检查文件中的网页地址、服务是否有效可用
2019/11/20 Javascript
[59:07]海涛为你详解DOTA2新版本“贤哲秘契”
2014/11/22 DOTA
[00:56]跨越时空加入战场 全新祈求者身心“失落奇艺侍祭”展示
2019/07/20 DOTA
Python实现的tab文件操作类分享
2014/11/20 Python
Python smtplib实现发送邮件功能
2018/05/22 Python
python: 自动安装缺失库文件的方法
2018/10/22 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
有趣的Python图片制作之如何用QQ好友头像拼接出里昂
2020/04/22 Python
win10从零安装配置pytorch全过程图文详解
2020/05/08 Python
HTML5 WebGL 实现民航客机飞行监控系统
2019/07/25 HTML / CSS
手机被没收检讨书
2014/02/22 职场文书
建设办主任四风问题整改思路和措施
2014/09/20 职场文书
四风问题个人对照检查剖析材料
2014/09/27 职场文书
正风肃纪剖析材料范文
2014/10/10 职场文书
2015年会计个人工作总结
2015/04/02 职场文书
护士业务学习心得体会
2016/01/25 职场文书
Go各时间字符串使用解析
2021/04/02 Golang
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
2021/05/26 Servers
Python 数据可视化工具 Pyecharts 安装及应用
2022/04/20 Python