一,為什麼要用異步請求
異步請求是一種編程模式,允許代碼在等待某些操作(如網絡請求、文件讀取等)完成時繼續執行其他任務,而不需要阻塞整個程序。(JavaScript的單線程特性)
|
同步請求 |
異步請求 |
|
阻塞主線程
|
非阻塞,保持UI響應
|
|
用户界面凍結
|
更好的用户體驗
|
|
無法同時處理多個任務
|
可以並行處理多個任務
|
|
用户體驗差
|
更高的資源利用率
|
二,Await與Promise.then的區別
|
特性 |
Promise.then() |
async/await |
|
語法風格
|
鏈式調用
|
同步寫法
|
|
錯誤處理
|
.catch()方法
|
try/catch塊
|
|
可讀性
|
回調嵌套可能複雜
|
更像同步代碼
|
|
調試
|
可能更難追蹤
|
堆棧跟蹤更清晰
|
|
變量作用域
|
每個then有獨立作用域
|
同一作用域內
|
async/await學習:
- async和 await 的基本使用
Promise.then學習:
- promise中的.then方法
三,並行請求的實現
使用場景:
- 同時獲取商品信息、用户評價、庫存狀態
- 並行請求多個數據源,快速渲染圖表
- 同時加載用户信息、好友列表、動態內容
- 並行獲取地圖數據、位置信息、周邊服務
實現方法:
- 原生方法
- Promise.all():當所有請求都成功時,返回一個包含所有請求結果的數組;如果有一個請求失敗,則立即返回失敗的原因。適用於需要所有數據才能繼續的場景。
- Promise.allSettled():等待所有請求完成,不管成功還是失敗,返回一個對象數組,每個對象表示對應請求的結果。適用於需要處理部分失敗的場景。
- Promise.race():返回最先完成的請求。適用於超時控制、競速場景。
- Promise.any():返回第一個成功的請求。適用於多備份數據源、容錯場景。
- 使用async/await結合Promise.all()
async function fetchUserData() {
try {
// 假設我們有兩個API端點
const userInfoPromise = fetch('https://api.example.com/user/info');
const userPostsPromise = fetch('https://api.example.com/user/posts');
// 使用Promise.all並行發起請求,並等待所有結果
const responses = await Promise.all([userInfoPromise, userPostsPromise]);
// 注意:fetch的響應體需要額外的方法(如.json())來讀取,它們也是異步的
const dataArray = await Promise.all(responses.map(response => response.json()));
console.log('用户信息:', dataArray[0]);
console.log('用户帖子:', dataArray[1]);
} catch (error) {
// 處理任何一個請求發生的錯誤
console.error('請求失敗:', error);
}
}
fetchUserData();
當需要處理成百上千的請求時,直接使用 Promise.all 可能會導致性能問題或觸發瀏覽器的併發限制。一個常見的解決方案是分批處理。
- 使用第三方庫(如axios.all)
使用 axios.all() 和 axios.spread()
axios.all() 本質上就是 Promise.all(),它可以同時發起多個請求。axios.spread() 則是一個工具函數,用於將所有請求結果的數組合併到單個函數參數列表中,方便我們使用具名變量來接收結果