微信小程序突破并发限制:Promise.all与顺序执行方案

作者:函数茶馆

时间:2026-10-22

浏览:642

本文详解微信小程序中Promise.all与顺序执行的区别。针对小程序单次并发请求限制10个的问题,介绍如何通过封装sequenceTasks函数,将Promise.all的并发执行改为顺序执行,从而支持批量上传超过10张图片而不报错。

文章目录

微信小程序Promise.all与顺序执行详解

前言与需求背景

一、前言

近期在进行小程序开发时,遇到一个表单提交需求:表单中包含图片字段。微信平台的处理机制要求先上传图片,后台返回图片名称和地址后,再将图片信息插入表单并提交。这里的核心问题是如何确保图片上传完成后,再执行表单提交。由于小程序中多图上传需逐张进行,因此需要解决多个图片请求完成后,再发起表单提交的业务逻辑。

Promise.all与Promise.race的区别

二、Promise.all和Promise.race

首先介绍Promise.all与Promise.race的区别。Promise.all(iterable)方法接收一个可迭代对象(通常为数组),当其中所有Promise对象都完成(resolve)或第一个失败(reject)时,返回一个新的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”。

前言与需求背景

顺序执行Promise解决方案

四、顺序Promise执行处理

由于Promise.all同时运行多个Promise对象,而小程序对并发数量有限制(一次只能并发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(传入值)。执行results.push(value),将每个值推入results数组,然后返回results数组。


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

pushValue是一个函数对象,将recordValue绑定到一个空数组[]中。第一个参数传null代表不改变函数this的指向,因此pushValue得到的是一个function (value)的函数,参数传入value。


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

task是函数,返回Promise对象,在此处即为上传图片函数。每张图片上传都创建一个函数,通过.then(pushValue),pushValue是function (value)的函数,value代表图片上传后的返回值。pushValue将返回值推入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());
}

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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章