V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lsk569937453
V2EX  ›  程序员

有个前端并发数的问题

  •  1
     
  •   lsk569937453 · 44 天前 · 1830 次点击
    这是一个创建于 44 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前文

    浏览器能够并行发送请求,但是每次并行发送请求的个数是有限制的,以 chrome 浏览器为例子:

    同一个域名下,同一个 GET 请求的并发数是 1 ,也就是说只有上一个请求结束,才会执行下一个请求,否则置入队列等待发送。 同一个域名下,不同 GET/POST 请求的并发数是 6 。当发送的请求数量达到 6 个,并且都没有得到响应时,后面的请求会置入队列等待发送。

    测试

        useEffect(
            () => {
                for (let i = 0; i < 10; i++) {
                    requestDelay();
                }
                console.log(randoms)
            },
            [])
    
        const SLEEP_MS = 1000;
    
        useEffect(() => {
            const interval = setInterval(() => {
                requestInstant();
    
            }, SLEEP_MS);
    
            return () => clearInterval(interval); // This represents the unmount function, in which you need to clear your interval to prevent memory leaks.
        }, [])
    

    requestDelay(); 这个方法在后端会无限超时(sleep 10000000 秒)。 requestInstant(); 这个方法会立即返回。

    当前的表象是:

    第一秒:requestDelay()已经发送出网络请求,后端已经收到。后续的 requestDelay()没有向后端发送请求,目测已经进入队列。
    第二秒到第十几秒:每秒都会 requestInstant()请求到后端,且立即返回。
    然后就是发送了五次 requestDelay()请求,后端已收到。
    后续的 requestInstant()请求已经卡住,一直没有向后端发送请求。
    
    

    疑问:我一直以为从第二秒开始就一直会每秒请求 requestInstant(),且立即返回。不知道为什么会后续又发送 5 次的 requestDelay()请求?老哥们帮忙解释下。

    第 1 条附言  ·  44 天前
    const requestDelay = async () => {
    const response = await axios.get('/api/delay')
    console.log(response.data)
    }
    const requestInstant = async () => {
    const response = await axios.get('/api/users')
    console.log(response.data)
    }

    server: {
    proxy: {
    '/api': {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
    secure: false,
    },
    },
    },
    请求的后端是本地的后端,接口/api/delay 在后端无限 sleep ,接口/api/users 在后端是马上返回
    10 条回复    2024-07-25 14:19:45 +08:00
    jones2000
        1
    jones2000  
       44 天前
    一个域名下同时请求并发是 5 个左右吧, 超了就要等。 可以使用批量动态域名来规避。
    lisongeee
        2
    lisongeee  
       44 天前
    浏览器这个不好控制,建议使用 https://www.npmjs.com/package/p-limit
    lsk569937453
        3
    lsk569937453  
    OP
       44 天前
    @jones2000 同一个域名下,不同 GET/POST 请求的并发数是 6 。我的意思是程序启动开始,10 次循环执行完。此时只有一个 requestDelay 发送了请求并且一直 hang 住,剩余的 9 个在消息队列中。而后面我每秒发一次 requestInstant 预期是应该不受影响。

    然而表象是在某个时间点,chrome 又把队列中的 5 个 requestDelay 请求拿出来发送网络请求且 hang 住,此时达到最大并发数 6 ,后续的 requestInstant 也进入队列,不再发送请求。并且影响了此域名下后续要发送的所有的 http 请求。
    jones2000
        4
    jones2000  
       44 天前
    @lsk569937453 自己做一个数据请求队列不就完事了。
    crz
        5
    crz  
       44 天前
    看起来意思是同时只要一个 delay 长链接,建议自己 promise 队列

    同一个 get 请求的并发数是 1 这个有出处吗?
    pursuer
        6
    pursuer  
       44 天前
    @lsk569937453 可能请求超时的时候策略不确定吧。这种依赖浏览器平台规则的特性随时可能变
    Projection
        7
    Projection  
       44 天前
    requestDelay() 前面要加 await 才行,不然你这样就是开启 10 个请求,后面 requestInstant() 只能排队
    remon
        8
    remon  
       44 天前
    贴一下请求的瀑布图吧。
    还有就是你的请求是 GET 还是 POST ,请求参数和地址是不是都一致?
    BTW:建议开启 HTTP2 可以避免阻塞
    IvanLi127
        9
    IvanLi127  
       44 天前
    我有个问题,你的前文是对的吗?我只看到浏览器在使用 http1 时会根据主机做请求的限制,没看到和请求方法在这方面有限制
    zhhbstudio
        10
    zhhbstudio  
       44 天前
    @lsk569937453 #3
    我觉得理论上的情况是:
    1. for 循环发送 6 个 requestDelay 请求被 hang 住,4 个进入队列
    2. 1 秒后每秒 1 个 requestInstant 加入队列。
    3. 超时后 4 个 delay 发出,然后 requestInstant 按顺序发出。

    PS:不熟悉 React ,也没实际遇到过这种情况
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1768 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:28 · PVG 08:28 · LAX 17:28 · JFK 20:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.