最近在做小程序的開發(fā),碰到的一個(gè)需求就是表單提交,提交的表單中包含有圖片,微信這邊的做法是先上傳圖片,后臺(tái)把圖片名稱和地址返回給你,然后你把圖片信息插入到表單的相應(yīng)位置再提交表單,這里就涉及到如何上傳完圖片的請(qǐng)求再上傳表單,而且微信小程序里面如果圖片是多個(gè)的話,也只能一張張上傳。簡(jiǎn)單來說就是上傳完圖片(多個(gè)請(qǐng)求),拿到返回值,再上傳表單,該如何做?
Promise.all(iterable) 方法指當(dāng)所有在可迭代參數(shù)中的 promises 已完成,或者第一個(gè)傳遞的 promise(指 reject)失敗時(shí),返回 promise。iterable為可迭代對(duì)象,但是一般為數(shù)組。返回值也是一個(gè)Promise對(duì)象。
需要明確的幾點(diǎn),Promise.all是并發(fā)執(zhí)行的同時(shí)運(yùn)行多個(gè)Promise對(duì)象,而且返回的Promise對(duì)象的參數(shù)是一個(gè)數(shù)組,數(shù)組中的各項(xiàng)也是可迭代對(duì)象執(zhí)行的順序返回。
Promise.race(iterable) 方法返回一個(gè)新的 promise,參數(shù)iterable中只要有一個(gè)promise對(duì)象”完成(resolve)”或”失?。╮eject)”,新的promise就會(huì)立刻”完成(resolve)”或者”失?。╮eject)”,并獲得之前那個(gè)promise對(duì)象的返回值或者錯(cuò)誤原因。所以只要iterable中有一個(gè)完成或者失敗就立即返回一個(gè)promise對(duì)象。根據(jù)race這個(gè)單詞為賽跑也能得出,最先到達(dá)的立即返回一個(gè)promise對(duì)象。
根據(jù)上面的定義,我們采用的Promise.all方法來完成我們的需求。
//存儲(chǔ)promise對(duì)象的數(shù)組 let promiseArr = []; //圖片地址數(shù)組 let imageList = []; //將圖片地址的上傳的promise對(duì)象加入到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) { //可以對(duì)res進(jìn)行處理,然后resolve返回 resolve(res); }, fail: function (error) { reject(error); }, complete: function (res) { }, }) }); promiseArr.push(promise) } //Promise.all處理promiseArr數(shù)組中的每一個(gè)promise對(duì)象 Promise.all(promiseArr).then((result) => { //對(duì)返回的result數(shù)組進(jìn)行處理 })
在做微信小程序的圖片上傳功能,這邊只能先上傳圖片,然后將圖片名和地址以response返回。
這里面我們就是用了promise.all方法但是有一個(gè)問題就是,promise.all是并發(fā)執(zhí)行的,但是微信小程序一次只能并發(fā)10個(gè)請(qǐng)求。
對(duì)于圖片上傳,可能需要一次上傳超過10張圖片,也就是一次并發(fā)超過10個(gè)請(qǐng)求,這樣的話微信就會(huì)報(bào)錯(cuò)
因?yàn)镻romise.all是同時(shí)運(yùn)行多個(gè)promsie對(duì)象,所以對(duì)于這種并發(fā)的數(shù)量,小程序是有限制的,一次只能并發(fā)10個(gè),所以如果想突破這種限制,可以進(jìn)行順序執(zhí)行每個(gè)Promise。
代碼如下:
//順序處理函數(shù) function sequenceTasks(tasks) { //記錄返回值 function recordValue(results, value) { results.push(value); return results; } let pushValue = recordValue.bind(null, []); let promise = Promise.resolve(); // 處理tasks數(shù)組中的每個(gè)函數(shù)對(duì)象 for (let i = 0; i < tasks.length; i++) { let task = tasks[i]; promise = promise.then(task).then(pushValue); } return promise; } //函數(shù)數(shù)組,每個(gè)函數(shù)的返回值是一個(gè)promise對(duì)象 let promiseFuncArr = []; //圖片地址數(shù)組 let imageList = []; //將圖片地址的上傳的函數(shù)加入到promiseFuncArr數(shù)組中 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) { //可以對(duì)res進(jìn)行處理,然后resolve返回 resolve(res); }, fail: function (error) { reject(error); }, complete: function (res) { }, }) }); }; promiseFuncArr.push(promiseTemp) } sequenceTasks(promiseFuncArr).then((result) => { //對(duì)返回的result數(shù)組進(jìn)行處理 });
首先recordValue函數(shù)傳入兩個(gè)值,一個(gè)是results是返回的數(shù)組,另一個(gè)是value,value是傳入的值,results.push(value);將每一個(gè)值push到results數(shù)組,然后再返回results數(shù)組。
let pushValue = recordValue.bind(null, []);
pushValue也是一個(gè)函數(shù)對(duì)象,將recordValue bind到一個(gè)[ ]數(shù)組中,第一個(gè)參數(shù)傳null代表,不改變函數(shù)this的指向,所以pushValue得到就是一個(gè)function (value)的函數(shù),參數(shù)傳入value。
promise = promise.then(task).then(pushValue);
task是函數(shù),函數(shù)返回promise對(duì)象,在我們這里就是上傳圖片函數(shù),每一張圖片上傳都創(chuàng)建一個(gè)函數(shù),then(pushValue),pushValue是function (value)的函數(shù),value代表的就是圖片上傳之后的返回值,pushValue將返回值push到result數(shù)組中,依次執(zhí)行,依次加入到result數(shù)組中,最后返回。就可以得到一個(gè)對(duì)象數(shù)組,數(shù)組中就是依次執(zhí)行返回的結(jié)果。
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()); }
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)