promise
思考题
- 现有
100
个接口数据请求,请你设计一套方案获取这些数据,维持并发为5
,全部数据请求完毕打印结果数组result
(为方便测试,可用setTimeout
模拟数据请求过程,另:需考虑个别接口请求失败的情况)
参考答案 👀
以下是一套可行方案:
js
const MAX_CONCURRENT_REQUESTS = 5
const TOTAL_REQUESTS = 100
// 模拟数据请求函数,使用setTimeout来模拟延迟,随机失败
function fetchData(url) {
return new Promise((resolve, reject) => {
const delay = Math.floor(Math.random() * 500) + 500 // 模拟0.5到1秒的随机延迟
setTimeout(() => {
if (Math.random() < 0.1) {
// 模拟10%的失败率
reject(`Failed to fetch ${url}`)
} else {
resolve(`Data from ${url}`)
console.log(url, 'ok')
}
}, delay)
})
}
async function fetchAllData(urls) {
const results = []
const executing = new Set()
for (const url of urls) {
const promise = fetchData(url)
.then(data => {
results.push(data)
})
.catch(error => {
console.error(error) // 打印错误信息
results.push(null) // 也可以选择其他方式处理失败的请求
})
.finally(() => {
executing.delete(promise)
})
executing.add(promise)
if (executing.size >= MAX_CONCURRENT_REQUESTS) {
await Promise.race(executing)
}
}
// 等待所有剩余的promise完成
while (executing.size > 0) {
await Promise.race(executing)
}
return results
}
// 生成100个示例URL
const urls = Array.from(
{ length: TOTAL_REQUESTS },
(_, i) => `https://example.com/data/${i}`
)
fetchAllData(urls)
.then(results => {
console.log('All data fetched:', results.length) // 确认结果数量
console.log('Results:', results) // 打印所有结果,包括失败的
})
.catch(error => {
console.error('Error fetching all data:', error)
})