一道前端面试题引发的学习

博客围绕前端批量请求数据的面试题展开,要求实现函数批量请求数据,通过 max 参数控制并发数,请求结束执行 callback 回调。还解析了串行、并行、并发的概念,以洗衣服和烧菜为例帮助理解,最后表示要实现该面试题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

请实现如下函数,可以批量请求数据,所有的 url 地址在 urls 参数中,同时可以通过 max 参数控制请求的并发数,当所有请求结束之后,需要执行 callback 回调函数,发送请求的函数可以直接使用 fetch 即可

小白陷阱

题中有一个关键词“并发”,对于我这种前端小白第一次解答这道题目就掉入陷阱了, 解成了并行,?

概念解析

说到并发我们可以先来理解‘串行’,‘并行’,‘并发’这三个概念
复制代码
  • 串行 当前任务执行完之后,才能执行下一个任务
  • 并行 多任务同时进行,互不影响
  • 并发 多任务在同一时间间隔发生

举个例子来帮助我们更好的理解:比如一个人洗衣服跟烧菜

  • 串行就是: 你只能先做其中的某一件事,做完之后才能去做下一件事情
  • 并行就是: 你右手烧菜,左手洗衣服同时进行
  • 并发就是: 你一会儿烧菜,一会儿又去洗衣服

到这里相信大家对上述的三个概念有了一点了解,接下里我们就来实现上面这道面试题:

试题实现

	<script type="text/javascript">
		let bodyElement = document.body
	    let urls = [
	      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2580986389,1527418707&fm=27&gp=0.jpg',
	      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1995874357,4132437942&fm=27&gp=0.jpg',
	      'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2640393967,721831803&fm=27&gp=0.jpg',
	      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1548525155,1032715394&fm=27&gp=0.jpg',
	      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2434600655,2612296260&fm=27&gp=0.jpg',
	      'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2160840192,133594931&fm=27&gp=0.jpg'
	    ]
	    let max = 2
	    let callback = () => {
	      console.log('所有请求完成了')
	    }

	    class Concurrent {
	    	constructor(urls, max, callback) {
	    		this.urls = urls
	    		this.max = max
	    		this.callback = callback
	    	  	this.currentIndex = 0
	    	}

	    	addQueue() {
	    		for(let i = 0, len = this.urls.length; i < len; i++) {
	    			if (this.currentIndex < this.max) {
    					this.request()
    					break
	    			}
    				
    				this.currentIndex++
	    		}
	    	}

	    	request() {
	    		let tiemout = Math.random() * 1000
	    		
	    		fetch(this.urls[this.currentIndex])
	    		.then(res => res.blob())
	    		.then(res => {
	    			let src = URL.createObjectURL(res)
	    			bodyElement.innerHTML += `<img src=${src} />`
	    		})
	    		.catch(fail => {
	    			
	    		})
	    		.finally(() => {
	    			if (++this.currentIndex < this.urls.length) {
	    			    // 用延时器是因为反应接口太快 以便于观察
	    				return setTimeout(() => {
		    				this.request()
		    			}, tiemout)
		    		}

		    		this.callback()
	    		})
	    	}
	    }

	    function sendRequest(urls, max, callback) {
			let concurrent = new Concurrent(urls, max, callback)
			concurrent.addQueue()
	    }

	    sendRequest(urls, max, callback)
	</script>
复制代码

谢谢大家的阅读,有错误之处,敬请指教。

转载于:https://juejin.im/post/5c8ded9be51d45365835345f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值