当前位置:首页 > 科技  > 软件

前端开发中大并发量如何控制并发数

来源: 责编: 时间:2024-05-07 09:15:44 288观看
导读写在前面最近在进行移动端h5开发,首页需要加载的资源很多,一个lottie动效需要请求70多张图片,但是遇到安卓webview限制请求并发数,导致部分图片请求失败破图。当然图片资源可以做闲时加载和预加载,可以减轻播放动效时资源

V2R28资讯网——每日最新资讯28at.com

写在前面

最近在进行移动端h5开发,首页需要加载的资源很多,一个lottie动效需要请求70多张图片,但是遇到安卓webview限制请求并发数,导致部分图片请求失败破图。当然图片资源可以做闲时加载和预加载,可以减轻播放动效时资源未加载的问题。V2R28资讯网——每日最新资讯28at.com

V2R28资讯网——每日最新资讯28at.com

上面代码基本实现了前端并发请求的需求,也基本满足需求,在生产中其实有很多已经封装好的库可以直接使用。比如:p-limit【https://github.com/sindresorhus/p-limit】V2R28资讯网——每日最新资讯28at.com

阅读p-limit源码

import Queue from 'yocto-queue';import {AsyncResource} from '#async_hooks';export default function pLimit(concurrency) { // 判断这个参数是否是一个大于0的整数,如果不是就抛出一个错误 if (  !((Number.isInteger(concurrency)  || concurrency === Number.POSITIVE_INFINITY)  && concurrency > 0) ) {  throw new TypeError('Expected `concurrency` to be a number from 1 and up'); } // 创建队列 -- 用于存取请求 const queue = new Queue(); // 计数 let activeCount = 0; // 用来处理并发数的函数 const next = () => {  activeCount--;  if (queue.size > 0) {   // queue.dequeue()可以理解为[].shift(),取出队列中的第一个任务,由于确定里面是一个函数,所以直接执行就可以了;   queue.dequeue()();  } }; // run函数就是用来执行异步并发任务 const run = async (function_, resolve, arguments_) => {  // activeCount加1,表示当前并发数加1  activeCount++;  // 执行传入的异步函数,将结果赋值给result,注意:现在的result是一个处在pending状态的Promise  const result = (async () => function_(...arguments_))();  // resolve函数就是enqueue函数中返回的Promise的resolve函数  resolve(result);  // 等待result的状态发生改变,这里使用了try...catch,因为result可能会出现异常,所以需要捕获异常;  try {   await result;  } catch {}  next(); }; // 将run函数添加到请求队列中 const enqueue = (function_, resolve, arguments_) => {  queue.enqueue(   // 将run函数绑定到AsyncResource上,不需要立即执行,对此添加了一个bind方法   AsyncResource.bind(run.bind(undefined, function_, resolve, arguments_)),  );  // 立即执行一个异步函数,等待下一个微任务(注意:因为activeCount是异步更新的,所以需要等待下一个微任务执行才能获取新的值)  (async () => {   // This function needs to wait until the next microtask before comparing   // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously   // when the run function is dequeued and called. The comparison in the if-statement   // needs to happen asynchronously as well to get an up-to-date value for `activeCount`.   await Promise.resolve();   // 判断activeCount是否小于concurrency,并且队列中有任务,如果满足条件就会将队列中的任务取出来执行   if (activeCount < concurrency && queue.size > 0) {    // 注意:queue.dequeue()()执行的是run函数    queue.dequeue()();   }  })(); }; // 接收一个函数fn和参数args,然后返回一个Promise,执行出队操作 const generator = (function_, ...arguments_) => new Promise(resolve => {  enqueue(function_, resolve, arguments_); }); // 向外暴露当前的并发数和队列中的任务数,并且手动清空队列 Object.defineProperties(generator, {  // 当前并发数  activeCount: {   get: () => activeCount,  },  // 队列中的任务数  pendingCount: {   get: () => queue.size,  },  // 清空队列  clearQueue: {   value() {    queue.clear();   },  }, }); return generator;}

整个库只有短短71行代码,在代码中导入了yocto-queue库,它是一个微型的队列数据结构。V2R28资讯网——每日最新资讯28at.com

手写源码

在进行手撕源码时,可以借助数组进行简易的实现:V2R28资讯网——每日最新资讯28at.com

class PLimit {    constructor(concurrency) {        this.concurrency = concurrency;        this.activeCount = 0;        this.queue = [];                return (fn, ...args) => {            return new Promise(resolve => {               this.enqueue(fn, resolve, args);            });        }    }        enqueue(fn, resolve, args) {        this.queue.push(this.run.bind(this, fn, resolve, args));        (async () => {            await Promise.resolve();            if (this.activeCount < this.concurrency && this.queue.length > 0) {                this.queue.shift()();            }        })();    }        async run(fn, resolve, args) {        this.activeCount++;        const result = (async () => fn(...args))();        resolve(result);        try {            await result;        } catch {        }        this.next();    }        next() {        this.activeCount--;        if (this.queue.length > 0) {            this.queue.shift()();        }    }}

小结

在这篇文章中,简要介绍了为什么要进行并发请求,阐述了使用请求池队列实现并发请求的设计思路,简要实现代码。V2R28资讯网——每日最新资讯28at.com

此外,还阅读分析了p-limit的源码,并使用数组进行简要的源码编写,以实现要求。V2R28资讯网——每日最新资讯28at.com

参考文章

  • 【源码共读】大并发量如何控制并发数https://juejin.cn/post/7179220832575717435?searchId=20240430092814392DC2208C545E691A26
  • 前端实现并发控制网络请求https://mp.weixin.qq.com/s/9uq2SqkcMSSWjks0x7RQJg。

本文链接:http://www.28at.com/showinfo-26-87046-0.html前端开发中大并发量如何控制并发数

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 如何优雅的变更Docker Desktop的镜像存储路径

下一篇: 盘点Lombok的几个操作,你记住了吗?

标签:
  • 热门焦点
  • 小米降噪蓝牙耳机Necklace分享:听一首歌 读懂一个故事

    在今天下午的小米Civi 2新品发布会上,小米还带来了一款新的降噪蓝牙耳机Necklace,我们也在发布结束的第一时间给大家带来这款耳机的简单分享。现在大家能见到最多的蓝牙耳机
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 7月安卓手机性价比榜:努比亚+红魔两款新机入榜

    7月登场的新机有努比亚Z50S Pro和红魔8S Pro,除了三星之外目前唯二的两款搭载超频版骁龙8Gen2处理器的产品,而且努比亚和红魔也一贯有着不错的性价比,所以在本次的性价比榜单
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • 学习JavaScript的10个理由...

    作者 | Simplilearn编译 | 王瑞平当你决心学习一门语言的时候,很难选择到底应该学习哪一门,常用的语言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz&ldquo;难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?&rdquo;这一番话,出自百合网联合创
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
  • 2021中国国际消费电子博览会与青岛国际软件融合创新博览会新闻发布会隆重举行

    9月18日,2021中国国际消费电子博览会与青岛国际软件融合创新博览会新闻发布会在青岛国际新闻中心隆重举行。发布会上青岛市政府领导联袂出席,对本次双展会情
Top