前幾天看了做者 zz_jesse
的 寫給新手前端的各類文件上傳攻略,從小圖片到大文件斷點續傳 ,學習了不少有關上傳的知識點。但在大文件分片上傳一塊,做者有說起分片上傳須要作併發限制處理,但他的demo並無作。抱着學習的心態,我又去網上學習了一番。。javascript
Promise.all()
方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。前端
const p = Promise.all([p1, p2, p3]);
複製代碼
上面代碼中, Promise.all()
方法接受一個數組做爲參數,p一、p二、p3都是 Promise 實例,若是不是,就會先調用下面講到的 Promise.resolve
方法,將參數轉爲 Promise 實例,再進一步處理。另外, Promise.all()
方法的參數能夠不是數組,但必須具備 Iterator 接口,且返回的每一個成員都是 Promise 實例。 p的狀態由p一、p二、p3決定,分紅兩種狀況。java
fulfilled
,p的狀態纔會變成 fulfilled
,此時p一、p二、p3的返回值組成一個數組,傳遞給p的回調函數。rejected
,p的狀態就變成 rejected
,此時第一個被 reject
的實例的返回值,會傳遞給p的回調函數。 const requestsLimit = (list, limit, asyncHandle) => {
return new Promise(resolve => {
let _limit = limit;
let recordList = []; // 記錄異步操做
let index = 0;
let listCopy = [].concat(list);
let asyncList = []; // 正在進行的全部併發異步操做
const asyncFunc = () => {
while(_limit--) {
const data = listCopy.shift()
if (data) asyncList.push(asyncHandle(data, index++));
}
Promise.all(asyncList).then(response => {
// 監聽並記錄每一次請求的結果
recordList = recordList.concat(response.filter(item => item));
if (listCopy.length !== 0) {
_limit = limit;
asyncList = [];
asyncFunc() // 數組還未迭代完,遞歸繼續進行迭代
} else {
// 全部併發異步操做都完成後,本次併發控制迭代完成,返回記錄結果
resolve(recordList)
}
})
}
asyncFunc()
})
}
複製代碼
var dataLists = [1,2,3,4,5,6,7,8];
requestsLimit(dataLists, 3, (item, index) => {
return new Promise(resolve => {
// 執行異步處理
setTimeout(() => {
// 篩選異步處理的結果
console.log(index)
if (item % 2 === 0) resolve({ item, index })
else resolve()
}, Math.random() * 5000)
});
}).then(response => {
console.log('finish', response)
})
複製代碼
console.log() git