V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
gromit1337

一个面试题

  •  
  •   gromit1337 · May 31, 2023 · 1907 views
    This topic created in 1061 days ago, the information mentioned may be changed or developed.

    优化 requestUserProfile 并发请求

    requestUserProfile 是个通用查询用户信息接口,通过传入 uid ,拿用户昵称 在一个支付宝群聊里有 10 多个用户,点击群聊信息,展示各个人的昵称 10 个并发请求,会阻塞接口 10 个依次请求,耗时久,显示昵称太慢 需要优化请求,在并发和耗时之间掌握一个平衡

    // 核心用户请求
    let _requestTime = 0;
    const requestProfile = (uid: string) => {
      // 这个方法的实现不能修改
      return Promise.resolve().then(() => {
        return new Promise<void>((resolve) => {
          setTimeout(() => {
            // 模拟 ajax 异步,1s 返回
            resolve();
          }, 1000);
        }).then(() => {
          _requestTime++;
          return {
            uid,
            nick: `nick-${uid}`,
            age: "18",
          };
        });
      });
    };
    
    /**
     *
     * @param uid uid
     * @param max 最多并发请求数量
     */
    const requestUserProfile = (uid, max = 2) => {}
    
    6 replies    2023-06-02 12:08:31 +08:00
    ChefIsAwesome
        1
    ChefIsAwesome  
       May 31, 2023 via Android
    可以再加几种变化:
    重试请求。失败的请求插到队列尾重试或者插到下一组重试,重试 n 次之后报错。
    按顺序显示结果。比方说并发的 1 、2 个请求,返回顺序是 2 、1 。要求 2 返回时不处理,1 返回时再依次处理 1 、2 。
    延迟。并发的一组结束之后,等待一段时间再开始下一组。
    gromit1337
        2
    gromit1337  
    OP
       May 31, 2023
    @ChefIsAwesome 有测试用例的
    ```javascript
    export default async () => {
    try {
    const star = Date.now();
    const result = await Promise.all([
    requestUserProfile("1"),
    requestUserProfile("2"),
    requestUserProfile("3"),
    requestUserProfile("1"),
    ]);

    if (Date.now() - star < 2000 || Date.now() - star >= 3000) {
    throw new Error("Wrong answer");
    }
    if (
    !isEqual(result, [
    {
    uid: "1",
    nick: "nick-1",
    age: "18",
    },
    {
    uid: "2",
    nick: "nick-2",
    age: "18",
    },
    {
    uid: "3",
    nick: "nick-3",
    age: "18",
    },
    {
    uid: "1",
    nick: "nick-1",
    age: "18",
    },
    ])
    ) {
    throw new Error("Wrong answer");
    }

    return _requestTime === 3;
    } catch (err) {
    console.warn("测试运行失败");
    console.error(err);
    return false;
    }
    };
    ```
    uncat
        3
    uncat  
       Jun 1, 2023   ❤️ 1
    并发控制,基于指数退避的超时重试( GPT4 写的)

    http://ix.io/4xdf
    uncat
        4
    uncat  
       Jun 1, 2023
    并发控制,基于指数退避的超时重试,确保请求 url 和 结果的顺序一致,如果超时或错误,则返回空值

    http://ix.io/4xdh
    zhy0216
        6
    zhy0216  
       Jun 2, 2023
    ```ts
    /**
    *
    * @param uid uid
    * @param max 最多并发请求数量
    */
    const queue: (() => unknown)[] = [];
    let activeCount = 0;
    let queueCursor = 0;
    const requestUserProfile = (uid: string, max = 2) => {
    return new Promise((resolve) => {
    const runF = async () => {
    activeCount++;
    const r = await requestProfile(uid);
    activeCount--;
    if (queueCursor < queue.length) {
    queue[queueCursor++]();
    }

    return resolve(r);
    };

    queue.push(runF);

    if (activeCount < max) {
    queue[queueCursor++]();
    }
    });
    };
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4715 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 10:06 · PVG 18:06 · LAX 03:06 · JFK 06:06
    ♥ Do have faith in what you're doing.