Norwegian Parcel Mail

    @masx200/async-task-current-limiter
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.0 • Public • Published

    async-task-current-limiter

    介绍

    异步任务限流器 async-task-current-limiter

    为了解决Error: EMFILE, too many open files的问题而生.

    有太多的文件已打开,已经不能再打开了。

    当您尝试一次在系统上打开太多文件时,就会发生这种情况。

    由于 Node 的异步特性,如果您fs.readFile快速连续执行很多或类似的操作,则可以轻松达到系统的 maxfiles 限制。

    安装教程

    yarn add https://github.com/masx200/async-task-current-limiter.git

    使用说明

    import AsyncLimiterClass from "@masx200/async-task-current-limiter";

    示例

    创建一个异步限流器对象,设定最大同时执行的异步任务数 30 个

    当成函数使用

    const asynclimiter = AsyncLimiterClass(30);

    或者当成类使用

    const asynclimiter = new AsyncLimiterClass(30);

    监听异步限流器的freefull的事件

    const listener = (data) => console.log(JSON.stringify(data));
    
    asynclimiter.target.on("free", listener);
    
    asynclimiter.target.on("full", listener);

    用异步限流包装器,包装一个要限流的异步操作函数,

    async function asyncread() {
        return await new Promise((s) => {
            setTimeout(() => {
                s("data:" + Math.random());
            }, Math.random() * 2000);
        });
    }
    
    const limitread = asynclimiter.asyncwrap(asyncread);

    进行大批量异步操作的限流

    for (let i = 0; i < 1000; i++) {
        setTimeout(() => {
            limitread().then(console.log);
        }, Math.random() * 5000);
    }

    原理

    通过调用被限流的异步函数,将调用传入内部队列。如果活跃调用小于最大并发数,将会被取出直接执行,反之则继续呆在队列中。

    当一个异步调用结束的时候,会从队列前取出调用执行。以此来保证异步调用的活跃量不高于限定值。

    API

    https://github.com/masx200/async-task-current-limiter/blob/master/dist/index.d.ts

    AsyncLimiterClass(max)

    1.当成函数使用

    2.当成类使用

    传入参数为限流器设定最大同时执行的任务数

    asynclimiter.target

    发布订阅的事件目标对象

    https://github.com/masx200/event-emitter-target

    事件 'free'

    在限流器空闲的时候触发

    可监听的参数类型为 statusdata接口

    事件 'full'

    在限流器占满的时候触发

    可监听的参数类型为 statusdata接口

    interface statusdata {
        status: 空闲状态;
        queue: {
            max: number;
            current: number;
        };
        limiter: {
            max: number;
            current: number;
        };
    }

    asynclimiter.asyncwrap(fun)

    异步限流包装器

    传入函数必须返回一个Promise,

    返回一个被限流的异步操作函数

    asynclimiter.status()

    获取限流器状态的函数,返回'free'或者'full'

    asynclimiter.limiter.max

    异步限流器的最大同时执行的任务数

    asynclimiter.limiter.current

    异步限流器的当前同时执行的任务数

    asynclimiter.queue.max

    异步限流器的异步任务队列总数

    asynclimiter.queue.current

    异步限流器的异步任务队列中已经执行的任务个数

    应用解决问题例子

    使用异步限流器解决同时打开过多文件的报错

    import fs from "fs";
    import AsyncLimiterClass from "@masx200/async-task-current-limiter";
    const asynclimiter = AsyncLimiterClass(50);
    
    declare const files: string[];
    const limitreadfile = asynclimiter.asyncwrap(fs.promises.readFile);
    files.forEach(async (file) => {
        const buf = await limitreadfile(file);
        console.log(buf);
    });

    Keywords

    none

    Install

    npm i @masx200/async-task-current-limiter

    DownloadsWeekly Downloads

    11

    Version

    2.1.0

    License

    MIT

    Unpacked Size

    35.3 kB

    Total Files

    8

    Last publish

    Collaborators

    • masx200