封装一个简易的并发请求方法


前言

前几天面试遇到的一道面试题,请手动实现一个并发请求函数,并获得每次请求得到的结果,因此这里记录一下。


一、并发请求

题目要求:有两个参数,分别是需要发送请求的url数组urls以及最大并发请求数maxNum,要求根据传入的参数maxNum实现最大并发请求并且以数组的形式返回所有的请求结果。

代码如下:

/**
 * 并发请求
 * @param {sting[]} urls 并发请求的url
 * @param {number} maxNum 最大并发数
 */
function concurRequest(urls, maxNum) {
    return new Promise((resolve) => {
        // 特殊情况,urls里没东西
        if (urls.length === 0) {
            resolve([])
            return
        }
        const results = [];
        let index = 0; // 下一个请求的下标
        let count = 0; // 请求的完成数量
        // 发送请求
        async function request() {
            if(index>=urls.length) return
            const i = index
            const url = urls[index]
            index++
            try {
                const resp = await fetch(url)
                // 将结果保存到数组中
                results[i] = resp
            } catch (error) {
                // error加入到results中
                results[i] = error
            } finally {
                count++
                // 判断是否所有请求都已完成
                if (count === urls.length) {
                    resolve(results)
                }
                request()
            }
        }
        // 最大并发数和数组长度取最小值作为循环数
        const times = Math.min(urls.length, maxNum)
        for (let n = 0; n < times; n++){
            request()
        }
    })

}

思路:
首先,因为是发生请求的函数,因此一定会异步调用,因为返回一个promise,
之后先进行特殊情况判断,如果传入的urls数组是空的,那么直接返回空数组即可。之后定义几个参数,分别是用于收集所有请求的返回结果(无论是成功还是失败)的数组results,下一个请求的数组下标index和当前请求完成的数量count。
然后定义一个发送请求的函数request,遍历urls数组,考虑到传入的最大并发数和urls数组长度的比较大小无法确定,因此取二者之间的最小值times进行遍历,之后循环调用request函数并传入当前请求的url,定义一个数组results用于收集所有请求的返回结果(无论是成功还是失败),当所有请求都完成时,通过调用promise的resolve方法将所有请求的结果数组results返回。

最后验证一下

const urls = []
for (let i = 1; i < 10; i++) {
    urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`)
}

concurRequest(urls, 3).then((response) => {
    console.log(response);
})

请添加图片描述
结果没有问题。


总结

本篇文章实现了一个简易的并发请求方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值