• 前端异步请求并发限流


    一道前端经典面试题,前端异步请求并发限流,主要需求是:一次最多有 max 个请求发出,如果有超出的请求待有请求响应完成后再开始继续请求,始终保持仅有 max 个,假设 max=10个,代码如下:

    主要原理为:令牌桶原理

    // 原理,使用令牌桶
    // 指 一次允许同时发出 max 个请求,这max个请求按执行时间返回具体结果,这 max 个有一个返回结果后,再开始执行一个
    // 创建一个异步执行任务
    function createTask(i) {
        return () => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(i);
                }, i * 100);
            });
        };
    }
    // 任务队列类
    class TaskQueue {
        constructor(max) {
            this.max = max || 10; // 当前可执行的任务数
            this.taskList = []; // 当前需要执行的任务列表
        }
        // 添加任务
        addTask(task) {
            this.taskList.push(task);
        }
        // 开始任务
        startTask() {
            setTimeout(() => {
                this.run();
            }, 0);
        }
        // 执行任务
        run() {
            console.log("this.max", this.max);
            const length = this.taskList.length;
            // 如果当前没有任务需要执行,则直接退出
            if (!length) {
                return;
            }
            // 取当前可执行的任务数与当前还剩的任务数的最小值,避免没任务执行但是还进行遍历的浪费
            const min = Math.min(this.max, length);
            // 遍历当前可执行的任务数
            for (let i = 0; i < min; i++) {
                // 开始占用一个任务空间,所以可执行的总任务数要减一
                this.max--;
                // 获取任务列表中的第一个任务,并将第一个任务从列表中删除
                const task = this.taskList.shift();
                // 以下为异步请求
                task()
                    .then((res) => {
                        console.log(res);
                    })
                    .catch((err) => {
                        console.log(err);
                    })
                    .finally(() => {
                        // 释放一个任务空间,所以可执行的总任务数要加一
                        this.max++;
                        // 一个请求执行结束,则释放出一个可执行的任务空间,继续调用 run 方法,遍历可执行的任务数,执行其他任务
                        this.run();
                    });
            }
        }
    }
    
    const taskQueue = new TaskQueue();
    
    for (let i = 0; i < 32; i++) {
        const task = createTask(i);
        taskQueue.addTask(task);
    }
    taskQueue.startTask();

    代码参考链接:https://www.bilibili.com/video/BV1XZ4y1y7BX?spm_id_from=333.337.search-card.all.click

  • 相关阅读:
    Tutorial: Getting started with fuzzing The Go Programming Language https://go.dev/doc/tutorial/fuzz
    在Bash脚本中引入alias的问题
    因果推断:效应估计的常用方法及工具变量讨论 https://mp.weixin.qq.com/s/oNu3wim9mXGzW2D9eeq_CQ
    It is illegal to take the address of such an element; if s[i] is the i'th byte of a string, &s[i] is invalid.
    Go 高性能编程技法 知乎 https://zhuanlan.zhihu.com/p/482547957
    /etc/passwd
    /sbin/nologin
    Go 1.18 is released!
    树形表格
    nginx 静态文件 文件乱码
  • 原文地址:https://www.cnblogs.com/beileixinqing/p/16299817.html
Copyright © 2020-2023  润新知