阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

简单介绍使用p-limit 限制并发数源码解析

278次阅读
没有评论

共计 2660 个字符,预计需要花费 7 分钟才能阅读完成。

导读 这篇文章主要为大家介绍了使用 p -limit 限制并发数源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
前言

并发是指在同一时间内处理的任务数量。例如,在一台服务器上同时运行多个 Web 服务器线程,可以同时处理多个客户端的请求。有时为了程序的稳定运行,我们需要限制并发的数量,p-limit 就是一个用 js 实现的控制并发数的库。

源码地址:sindresorhus/p-limit

使用

下面是官方提供的使用示例:

import pLimit from 'p-limit';
const limit = pLimit(1);
const input = [limit(() => fetchSomething('foo')),
    limit(() => fetchSomething('bar')),
    limit(() => doSomething())
];
// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);

在代码的第一行,使用了 pLimit(1) 来创建一个 p-limit 实例,并将并发限制设为 1。这意味着,在任意时刻,只能有一个 Promise 在运行。

在第四行,使用了 limit(() => fetchSomething(‘foo’)) 来包装一个异步函数,并返回一个 Promise。同样的方式,在第五、六行也包装了其他两个异步函数。

最后,使用 Promise.all 方法来等待所有 Promise 的完成,并在完成后将结果输出到控制台。由于 p-limit 的限制,这些 Promise 只会按顺序一个一个地运行,保证了并发的数量不会超过 1。

源码分析
import Queue from 'yocto-queue';
export default function pLimit(concurrency) {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;
}

yocto-queue 是一种允许高效存储和检索数据的数据结构。前边的章节分析过它的源码,详情参见:源码共读 |yocto-queue 队列 链表

pLimit 函数接受一个参数,并发数,首先函数判断参数是否是数组类型,或者是否能够转换成数字类型,如果不能,抛出一个错误。

之后定义了一个队列来存储待执行的函数,并使用一个计数器来记录当前正在运行的函数的数量。

const next = () => {
        activeCount--;
        if (queue.size > 0) {queue.dequeue()();}
    };
    const run = async (fn, resolve, args) => {
        activeCount++;
        const result = (async () => fn(...args))();
        resolve(result);
        try {await result;} catch {}
        next();};

在代码的 next 函数中,如果队列不为空,则从队列中取出一个函数并执行。这个函数的执行会导致计数器的值减 1。

在代码的 run 函数中,使用了 async/await 语法来执行传入的函数 fn。它还使用了 resolve 函数将函数的返回值包装成一个 Promise,并将这个 Promise 返回给调用者。在函数执行完成后,调用 next 函数来执行下一个函数。

const enqueue = (fn, resolve, args) => {queue.enqueue(run.bind(undefined, fn, resolve, args));
    (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();
        if (activeCount  0) {queue.dequeue()();}
    })();};

在代码的 enqueue 函数中,使用了 queue.enqueue 方法将传入的函数 fn 加入队列。然后,它使用了 async/await 语法来在下一个微任务中检查当前的并发数量是否小于设定的并发限制。如果是,则从队列中取出一个函数并执行。

const generator = (fn, ...args) => new Promise(resolve => {enqueue(fn, resolve, args);
});
Object.defineProperties(generator, {
    activeCount: {get: () => activeCount,
    },
    pendingCount: {get: () => queue.size,
    },
    clearQueue: {value: () => {queue.clear();
        },
    },
});
return generator;

在代码的 generator 函数中,使用了 new Promise 语法来生成一个新的 Promise,并在其中调用了 enqueue 函数。这样,每次调用生成的函数时,都会生成一个新的 Promise,并将函数加入队列。

最后,使用了 Object.defineProperties 方法来为生成的函数添加属性。这些属性可以用来查询当前的并发数量和等待队列的大小,以及清空等待队列。

总结

控制并发的实现方式有很多种。例如,可以使用信号量或队列来控制并发请求的数量。也可以使用计数器或令牌桶算法来限制请求的频率。还可以使用拒绝服务(DoS)防护系统来检测异常请求流量并进行限制

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计2660字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19348
评论数
4
阅读量
7806645
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板 1Panel:小白轻松构建 Web 服务与面板加固指南 哈喽,我是星哥,经常有人问我不...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛NAS-12:开源笔记的进化之路,效率玩家的新选择

星哥带你玩飞牛 NAS-12:开源笔记的进化之路,效率玩家的新选择 前言 如何高效管理知识与笔记,已经成为技术...
星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛 NAS-14:解锁公网自由!Lucky 功能工具安装使用保姆级教程 作为 NAS 玩家,咱们最...
飞牛NAS玩转Frpc并且配置,随时随地直连你的私有云

飞牛NAS玩转Frpc并且配置,随时随地直连你的私有云

飞牛 NAS 玩转 Frpc 并且配置,随时随地直连你的私有云 大家好,我是星哥,最近在玩飞牛 NAS。 在数...
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...
Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集 在云原生体系中,Prometheus 已成为最主流的监控与报警...
小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比 星哥玩云,带你从小白到上云高手。今天咱们就来聊聊——什...
零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face 免费服务器 +Docker 快速部署 HertzBeat 监控平台 ...