今天遇到一個需求就是,需要在for循環中,進行axios異步請求。一般這個這個時候就遇到兩個問題
- 因爲你的請求是在for循環中,而且又是異步的請求所以,請求出來的數據順序錯亂
- 還有就是在for裏 等所有的異步請求完成之後,再去處理數據。這時你就會發現。它是先走了異步請求下邊的代碼,因爲這個是線程問題,在一個就是異步的,它不會等着你完成請求之後再去執行。因爲JS運行在瀏覽器中,是單線程的
for (let i = 0; i < 5; i++) {
setTimeout(function() { //這裏一般是axios請求 現在模仿異步 看一下打印的結果
console.log(i)
}, Math.random() * 3000)
}
會發現打印的下標他的順序是錯亂的
解決方案 利用es6 中的 let 和Promise.all方法來解決
biPromise.all方法就是專門來解決 多個異步處理的
biPromise的基礎用法看這https://blog.csdn.net/qq_46124502/article/details/106500810
let promiseList = []
for (let i = 0; i < 5; i++) {
//promiseList這裏要放到push數組裏,原因是 如果用變量。一直就是最後一個, 或者不用push的話 ,也可以用閉包的形式來
promiseList.push(new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i)//如果想要返回多個數據resolve([v,i])
}, Math.random() * 3000);
}));
}
//放到循環外邊 因爲 rspList是一個數組
Promise.all(promiseList).then((rspList)=> {
rspList.map((val)=> {
console.log(val);
});
});
當時你也可以用遞歸去實現。但遞歸影響運行速度,因爲它不是併發的。
如果在所有異步請求完成之後再去處理數據,
let promiseList = []
for (let i = 0; i < 5; i++) {
promiseList.push(new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i)
}, Math.random() * 3000);
}));
}
Promise.all(promiseList).then((rspList)=> { //這個也可以接收多個Promise.all([promiseList,promiseList2])
rspList.map((val)=> {
console.log(val); // 依次輸出0-4
});
}).then(()=>{
console.log("所有異步請求已經完成")
})
希望可以幫助到你