最(zui)近在做(zuo)小程序的(de)開發,碰到(dao)的(de)一個(ge)(ge)需求就(jiu)(jiu)(jiu)是(shi)表單(dan)提交(jiao),提交(jiao)的(de)表單(dan)中包含(han)有(you)圖片(pian)(pian),微信(xin)這邊的(de)做(zuo)法是(shi)先上傳(chuan)(chuan)圖片(pian)(pian),后(hou)臺(tai)把(ba)圖片(pian)(pian)名稱和(he)地址返(fan)(fan)回給你,然后(hou)你把(ba)圖片(pian)(pian)信(xin)息插(cha)入(ru)到(dao)表單(dan)的(de)相應(ying)位(wei)置(zhi)再提交(jiao)表單(dan),這里就(jiu)(jiu)(jiu)涉(she)及(ji)到(dao)如(ru)何上傳(chuan)(chuan)完圖片(pian)(pian)的(de)請(qing)求再上傳(chuan)(chuan)表單(dan),而且微信(xin)小程序里面如(ru)果圖片(pian)(pian)是(shi)多個(ge)(ge)的(de)話,也(ye)只(zhi)能一張(zhang)張(zhang)上傳(chuan)(chuan)。簡單(dan)來說(shuo)就(jiu)(jiu)(jiu)是(shi)上傳(chuan)(chuan)完圖片(pian)(pian)(多個(ge)(ge)請(qing)求),拿(na)到(dao)返(fan)(fan)回值,再上傳(chuan)(chuan)表單(dan),該如(ru)何做(zuo)?
Promise.all(iterable) 方法指當所有在可迭代參數中的 promises 已完成,或者第一個傳遞的 promise(指 reject)失敗時,返回 promise。iterable為可迭代對象,但是一般為數組。返回值也是一個Promise對象。
需(xu)要明確的(de)(de)幾點,Promise.all是并(bing)發(fa)執(zhi)行的(de)(de)同(tong)時運行多個Promise對(dui)象,而且返(fan)回(hui)的(de)(de)Promise對(dui)象的(de)(de)參數(shu)是一個數(shu)組(zu),數(shu)組(zu)中的(de)(de)各項也是可迭(die)代對(dui)象執(zhi)行的(de)(de)順(shun)序(xu)返(fan)回(hui)。
Promise.race(iterable) 方(fang)法返回一個新(xin)的(de)(de)(de) promise,參數iterable中(zhong)只要有一個promise對象”完成(resolve)”或(huo)”失(shi)敗(bai)(reject)”,新(xin)的(de)(de)(de)promise就會立(li)刻”完成(resolve)”或(huo)者(zhe)”失(shi)敗(bai)(reject)”,并(bing)獲得(de)之(zhi)前那個promise對象的(de)(de)(de)返回值(zhi)或(huo)者(zhe)錯誤原因(yin)。所以只要iterable中(zhong)有一個完成或(huo)者(zhe)失(shi)敗(bai)就立(li)即返回一個promise對象。根據race這個單詞為賽跑也能得(de)出,最(zui)先到達的(de)(de)(de)立(li)即返回一個promise對象。
根據上面的(de)定義,我們(men)采用的(de)Promise.all方法來完成(cheng)我們(men)的(de)需(xu)求。
//存儲promise對象的數組
let promiseArr = [];
//圖片地址數組
let imageList = [];
//將圖片地址的上傳的promise對象加入到promiseArr
for (let i = 0; i < imageList.length; i++) {
let promise = new Promise((resolve, reject) => {
//微信圖片上傳
wx.uploadFile({
url: '//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數組進行處理
})
在做(zuo)微(wei)信小程(cheng)序的圖片(pian)上傳(chuan)功能(neng)(neng),這(zhe)邊只能(neng)(neng)先上傳(chuan)圖片(pian),然后將(jiang)圖片(pian)名和(he)地址以response返回(hui)。
這里面(mian)我們就是用了promise.all方法但是有一個(ge)問題就是,promise.all是并(bing)發執行的,但是微信小程序一次只能并(bing)發10個(ge)請求。
對于圖片(pian)上傳,可能需要一(yi)次上傳超(chao)過10張圖片(pian),也(ye)就是一(yi)次并(bing)發超(chao)過10個請(qing)求(qiu),這樣的(de)話微信就會報錯
因為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: '//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數組進行處理
});
首先(xian)recordValue函數(shu)(shu)傳入兩個值(zhi),一(yi)個是(shi)results是(shi)返(fan)回的(de)數(shu)(shu)組(zu),另一(yi)個是(shi)value,value是(shi)傳入的(de)值(zhi),results.push(value);將(jiang)每一(yi)個值(zhi)push到results數(shu)(shu)組(zu),然后再返(fan)回results數(shu)(shu)組(zu)。
let pushValue = recordValue.bind(null, []);
pushValue也(ye)是一(yi)(yi)個(ge)函(han)數對(dui)象,將recordValue bind到一(yi)(yi)個(ge)[ ]數組中,第一(yi)(yi)個(ge)參(can)(can)數傳(chuan)null代表,不改(gai)變(bian)函(han)數this的指向,所以pushValue得到就是一(yi)(yi)個(ge)function (value)的函(han)數,參(can)(can)數傳(chuan)入(ru)value。
promise = promise.then(task).then(pushValue);
task是(shi)函(han)(han)數(shu)(shu),函(han)(han)數(shu)(shu)返(fan)(fan)(fan)回promise對象(xiang),在(zai)我們這里就(jiu)是(shi)上傳(chuan)(chuan)圖片(pian)函(han)(han)數(shu)(shu),每一(yi)(yi)張圖片(pian)上傳(chuan)(chuan)都創(chuang)建一(yi)(yi)個函(han)(han)數(shu)(shu),then(pushValue),pushValue是(shi)function (value)的函(han)(han)數(shu)(shu),value代表的就(jiu)是(shi)圖片(pian)上傳(chuan)(chuan)之后的返(fan)(fan)(fan)回值(zhi),pushValue將返(fan)(fan)(fan)回值(zhi)push到result數(shu)(shu)組(zu)中,依(yi)次(ci)(ci)執行,依(yi)次(ci)(ci)加(jia)入(ru)到result數(shu)(shu)組(zu)中,最后返(fan)(fan)(fan)回。就(jiu)可以得到一(yi)(yi)個對象(xiang)數(shu)(shu)組(zu),數(shu)(shu)組(zu)中就(jiu)是(shi)依(yi)次(ci)(ci)執行返(fan)(fan)(fan)回的結果。
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());
}