Chrome 浏览器的请求机制:同一个域名同时最多只能建立 6 个 TCP 连接,也就是说单个域名最大的并发量是 6
如果并发请求达到一定量级的时候,堆积了无数的调用栈就有可能会导致内存溢出
并行请求
-
使用场景
将所有请求一次性全部发送出去,然后等待接收全部的结果
适合请求数固定且不需要按照预期顺序执行异步任务的情况
-
Promise.all方法
(async () => { const [data1, data2, data3] = await Promise.all([ Promise.resolve(1), Promise.resolve(2), Promise.resolve(3), ]) .catch(e => { console.error(e) }) console.log(`Received data: ${data1}`) console.log(`Received data: ${data2}`) console.log(`Received data: ${data3}`) })() 复制代码
如果其中某个异步任务出现异常,则所有任务都会视为失败,此时 Promise 直接进入 rejected 状态
-
Promise.allSettled方法
(async () => { const response = await Promise.allSettled([ Promise.reject(1), Promise.resolve(2), Promise.resolve(3), ]) console.log('Received data:', response) })() 复制代码
[ { "status": "rejected", "reason": 1 }, { "status": "fulfilled", "value": 2 }, { "status": "fulfilled", "value": 3 }, ] 复制代码
无论成功或异常,都将返回对应的状态,由开发者根据业务过滤自己想要的结果
串行请求
-
使用场景
按照预期顺序执行异步任务,即等待上一个 await 执行完毕后,再接着执行下一个
适合请求数固定且需要按照预期顺序执行异步任务的情况
-
for-of循环
(async () => { const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)] for (const [index, promise] of promises.entries()) { console.log(`Received data: ${await promise}`) } console.log('Finished') })() 复制代码
-
异步遍历器
(async () => { const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)] try { for await (const data of promises) { console.log('Received data:', data) } } catch (e) { console.error(e) } console.log('Finished') })() 复制代码
量化的并发请求数控制
-
优化场景
大文件的分片上传请求;批量下载文件的请求
-
通过while循环实现并发
const invariable = ({ list = [], limit = 3, singleComplete = () => {} }) => { return new Promise((resolve, reject) => { let completeCount = 0, total = list.length limit = total > limit ? limit : total while(limit--) { const { url, data } = list.shift() recursion(url, data) } }) } 复制代码
-
通过递归实现请求数控制
const recursion = (url, data) => { fetchFileStream(url).then(blob => { singleComplete({ data, response: blob }) completeCount += 1 if (list.length) { const { url, data } = list.shift() recursion(url, data) } else { completeCount === total && resolve(true) } }) } 复制代码
往期回顾
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END