整理了一道前端字节的面试题,分享给大家。如有问题,欢迎指正!
题目描述:
请实现以下函数,可以批量请求数据,所有的url地址在参数urls中,通过max参数控制请求并发数,当所有请求结束后,需要执行callback回调函数。发请求的函数直接使用fetch即可。
function handleFetchQueue(urls, max, callback){
// TODO
}
思路
1、开始并发max个请求(如总数不超过max按照实际总数来)
2、每一个请求结束后开启下一个请求
3、哎,这是不是得用到递归啊,没错!
4、每个请求的结果无论成功还是失败还是存到results数组中吧,万一callback要用呢
5、啥时候执行回调函数呢,这个统计一下成功失败的数量等于url总数就行,也可以直接用results数组的长度判断
开写代码
function handleFetchQueue (urls, max, callback) {
const originUrlCount = urls.length // 原始url的数量
const results = []
// 1、同时发起max个请求
for (let i = 0; i < urls.length && i < max; i++) {
handleOneRequest(urls.shift())
}
function handleOneRequest (url) {
console.log('start', url)
fetch(url).then(res => {
results.push(res)
}).catch(err => {
results.push(err)
}).finally(() => {
console.log('end', url)
// 2、完成1个请求,队列中随便退出一个,加入下一个
if (urls.length) {
handleOneRequest(urls.shift())
}
if (results.length === originUrlCount) {// 请求全部完成
callback(results)
}
})
}
}
完整测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function handleFetchQueue (urls, max, callback) {
const originUrlCount = urls.length // 原始url的数量
const results = []
// 1、同时发起max个请求
for (let i = 0; i < urls.length && i < max; i++) {
handleOneRequest(urls.shift())
}
function handleOneRequest (url) {
console.log('start', url)
fetch(url).then(res => {
results.push(res)
}).catch(err => {
results.push(err)
}).finally(() => {
console.log('end', url)
// 2、完成1个请求,队列中随便退出一个,加入下一个
if (urls.length) {
handleOneRequest(urls.shift())
}
if (results.length === originUrlCount) {// 请求全部完成
callback(results)
}
})
}
}
handleFetchQueue([
"http://baidu.com1",
"http://bytedance.com2",
"http://taobao.com3",
"http://baidu.com4",
"http://bytedance.com5",
], 2, (res) => {
console.log("全部执行完毕", res)
})
</script>
</head>
</html>