最近在作小程序的開發,碰到的一個需求就是表單提交,提交的表單中包含有圖片,微信這邊的作法是先上傳圖片,後臺把圖片名稱和地址返回給你,而後你把圖片信息插入到表單的相應位置再提交表單,這裏就涉及到如何上傳完圖片的請求再上傳表單,並且微信小程序裏面若是圖片是多個的話,也只能一張張上傳。簡單來講就是上傳完圖片(多個請求),拿到返回值,再上傳表單,該如何作?前端
Promise.all(iterable)
方法指當全部在可迭代參數中的 promises 已完成,或者第一個傳遞的 promise(指 reject)失敗時,返回 promise。iterable爲可迭代對象,可是通常爲數組。返回值也是一個Promise對象。
須要明確的幾點,Promise.all是併發執行的同時運行多個Promise對象,並且返回的Promise對象的參數是一個數組,數組中的各項也是可迭代對象執行的順序返回。vue
Promise.race(iterable)
方法返回一個新的 promise,參數iterable中只要有一個promise對象」完成(resolve)」或」失敗(reject)」,新的promise就會馬上」完成(resolve)」或者」失敗(reject)」,並得到以前那個promise對象的返回值或者錯誤緣由。因此只要iterable中有一個完成或者失敗就當即返回一個promise對象。根據race這個單詞爲賽跑也能得出,最早到達的當即返回一個promise對象。npm
根據上面的定義,咱們採用的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個請求。api
對於圖片上傳,可能須要一次上傳超過10張圖片,也就是一次併發超過10個請求,這樣的話微信就會報錯數組
由於Promise.all是同時運行多個promsie對象,因此對於這種併發的數量,小程序是有限制的,一次只能併發10個,因此若是想突破這種限制,能夠進行順序執行每一個Promise。
代碼以下: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數組進行處理
});
複製代碼
首先recordValue函數傳入兩個值,一個是results是返回的數組,另外一個是value,value是傳入的值,results.push(value);將每個值push到results數組,而後再返回results數組。bash
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數組中,最後返回。就能夠獲得一個對象數組,數組中就是依次執行返回的結果。
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());
}
複製代碼
(來自公衆號:前端八點半)