V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
lqzhgood
V2EX  ›  分享创造

axios-multi-down 如果前端请求有 1G~🐶

  •  
  •   lqzhgood · 2023-10-07 10:32:18 +08:00 · 1454 次点击
    这是一个创建于 448 天前的主题,其中的信息可能已经有所发展或是发生改变。

    axios-multi-down

    Axios 插件,通过 Range 特性, 将 大文件 分割,并发多个 Axios 请求加快大文件下载速度。

    起因

    最近在面试,聊到个人项目 Shmily (https://v2ex.com/t/944851), 这个项目是将 QQ 、微信、短信等各种数据汇总并时间线展示的一个项目,其中子项目 Shmily-Show 一个难点就是纯前端处理大量的聊天记录(总计 1.41G ,最大单文件 240M )。

    面试官基于此引申出一个问题:如果前端单一请求大小有 1G,,可以和后端采取哪些方案加速? Shmily 是一个本地的 Web 应用,所以并不存在这个传输问题。生产中这是一个不合理的需求,应该从为什么有 1G 的角度去考虑。面试官也一再强调这只是假设情况,但不妨碍这是一个有趣的问题,就像刮刮乐还没刮开,就已经在想 500 万怎么花。 more...

    其中一个措施是分块传输,然后就写了这个库 axios-multi-down

    Demo

    感觉也没啥说的,直接上 Demo 吧,Demo 的呈现想法来自于 FlashGet-网际快车

    https://lqzhgood.github.io/axios-multi-down

    优点

    • 自动探测服务器是否支持分块,不支持自动回退单一请求
    • 支持控制并发数量
    • 支持 Block 下载失败自动重试
    • ERROR_MODE.WAIT 模式支持全部下载完成后等待,可以手动对失败 Block 重试和操作,等待直到全部成功后返回

    有啥用

    好像没啥用,大文件去用 迅雷、Aria2 等更专业~

    如果是需要请求 1 个 G 的 Api ,先让 PM 祭天吧~

    就当锻炼锻炼各种条件下的 Promise 使用,面试考这个真是超级多呀~ 🐶

    是不是还能骗个 star? 听说对找工作有用啊! Github

    10 条回复    2023-10-07 15:04:36 +08:00
    subframe75361
        1
    subframe75361  
       2023-10-07 10:49:30 +08:00
    单纯好奇,不用 await 的原因是?
    abigmiu
        2
    abigmiu  
       2023-10-07 11:06:08 +08:00
    下载的分段数据与放内存里面了吗
    cheetah
        3
    cheetah  
       2023-10-07 11:29:31 +08:00
    小建议:代码可读性有提升空间
    举例:

    ```
    let r;
    if (downConfigUse.max === 1) {
    r = await downByOne<T, D>(axios, axiosConfig, downConfigUse);
    } else {
    r = await downByMulti<T, D>(axios, axiosConfig, downConfigUse, queue, contentLength);
    }
    return r;
    ```

    是否这样更好呢?

    ```
    if (downConfigUse.max === 1) {
    return downByOne<T, D>(axios, axiosConfig, downConfigUse);
    }
    return downByMulti<T, D>(axios, axiosConfig, downConfigUse, queue, contentLength);
    ```
    cheetah
        4
    cheetah  
       2023-10-07 11:30:37 +08:00
    然后代码里有很多嵌套的 if-else ,其实可以通过 early return 等方法消除掉
    lqzhgood
        5
    lqzhgood  
    OP
       2023-10-07 12:04:07 +08:00
    @cheetah #3 谢谢建议
    不写成 return await 有两个原因
    1. 个人原因,为了调试方便 我一般 return value ,不 return fn
    2. return await Eslint 也不建议,详见 https://eslint.org/docs/latest/rules/no-return-await

    对于 early return , 代码中复杂的逻辑(超过 3 层 if )已有 early return 处理。
    剩下的都不是复杂逻辑而且后面还有代码,个人觉得还能接受。 不过确实完全修改后会更好

    谢谢建议~ 给一朵 💐
    lqzhgood
        6
    lqzhgood  
    OP
       2023-10-07 12:06:33 +08:00
    @subframe75361 不太清楚你说的不用 await 是指的哪方面?
    lqzhgood
        7
    lqzhgood  
    OP
       2023-10-07 12:10:30 +08:00
    @abigmiu #2 目前都是放内存,因为 axios 目前浏览器还不支持 responseType = 'staem'
    需要等到 axios 使用 fetch 作为 adapter 后才支持。

    到时候可以用使用 steam 结合 FileSystem 直接存文件。
    subframe75361
        8
    subframe75361  
       2023-10-07 14:03:30 +08:00
    @lqzhgood #6 回调层数多了些。而且你发的 eslint 链接里的规则也已经弃用了
    subframe75361
        9
    subframe75361  
       2023-10-07 14:04:50 +08:00
    另外我个人更偏好于 三元运算符
    lqzhgood
        10
    lqzhgood  
    OP
       2023-10-07 15:04:36 +08:00
    @subframe75361 #8 多层异步用 await 没法写吧~

    第一层 全部下载完成的 resolveAll 要放到最下层,最后一个下载完的 Promise 里面去。
    并且队列最后一个并不等于最后下载完的。

    中间都是并发的,并不是 one by one 呀~ 只能回调吧~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2800 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 02:54 · PVG 10:54 · LAX 18:54 · JFK 21:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.