首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >大厂面试经(二):前端请求如何将多次提交压缩成一次提交?

大厂面试经(二):前端请求如何将多次提交压缩成一次提交?

作者头像
代码简单说
发布2026-06-16 16:07:48
发布2026-06-16 16:07:48
630
举报
文章被收录于专栏:代码简单说代码简单说

大厂面试经(二):前端请求如何将多次提交压缩成一次提交?

tag:前端防抖 | 请求合并 | Vue | 面试题 | 高级优化

“你知道在用户频繁点击按钮时,怎么把这些请求压缩成一次提交吗?” 面试官盯着我,轻轻点了点桌面。我知道,这道题不止考防抖,它想要的,是架构级的思考方式。


🧠 我踩过的一个“高频点击”坑

有一次做一个后台运营功能,页面上有个“批量发布”按钮。用户在点击时,会发起一个 API 请求,把选中的文章一键发布。

结果上线后发现,有运营同事习惯性猛点按钮……短短几秒钟,服务器收到十几个重复请求,导致文章被重复推送,还顺带炸了个 Redis 队列。

当时我用了节流+disabled 的土办法解决了问题。但直到有天面试被问到“如何把多次点击合并成一次请求”,我才意识到:节流只是权宜之计,要真正优雅地处理这种情况,得升维思考


🚀 把“防抖节流”升维成“请求合并”

在这里插入图片描述
在这里插入图片描述

大多数人会想到节流(throttle)或防抖(debounce):

代码语言:javascript
复制
const submit = debounce(() => {
  api.post('/submit', data);
}, 500);

但面试官真正想听到的,不是这一行代码,而是为什么这样做,以及还有没有更优解

于是我在项目里逐步尝试了几种方式,每一步都更抽象、更通用。


💡 解法一:最基础的防抖/节流(适合用户主动操作)

适用于输入框搜索、按钮点击。比如:

代码语言:javascript
复制
const submitForm = debounce(() => {
  axios.post('/submit', getFormData());
}, 800);

优点是简单直观,缺点是粒度太细,不适合组件通信或高频场景


💡 解法二:基于请求缓存的“合并机制”(适合并发场景)

这是我后来面试讲到的重点方案,很多人没讲到这里,面试官就已经开始点头了。

核心思路:
  1. 用户每次点击不会立即请求,而是将请求参数加入一个“队列”;
  2. 设置一个定时器,几百毫秒后统一发一次请求
  3. 发请求时将“所有参数”打包;
  4. 服务端返回后统一响应。
封装代码如下:
代码语言:javascript
复制
// 单例请求管理器
class RequestMerger {
  constructor() {
    this.queue = [];
    this.timer = null;
  }

  enqueue(data) {
    this.queue.push(data);
    if (!this.timer) {
      this.timer = setTimeout(() => {
        this.flush();
      }, 300); // 合并时间窗口
    }
  }

  flush() {
    const merged = [...this.queue];
    this.queue = [];
    this.timer = null;

    axios.post('/api/submit', merged)
      .then(res => {
        // TODO: 回调处理
      });
  }
}

// 使用方式
const merger = new RequestMerger();

function onClickSubmit(itemData) {
  merger.enqueue(itemData);
}

这个设计和“打包发货”很像:每次有人下单就放进筐里,过几百毫秒统一寄出。


💡 解法三:全局事件代理 + 请求合并(适合多个组件并发)

如果你的场景是多个组件或模块在几乎同时提交请求,比如:

  • 多个子表单
  • 多个异步上传操作
  • 多个模块内部统一处理

你可以用事件总线或全局管理器封装:

代码语言:javascript
复制
// submitBus.js
const listeners = [];
let timer = null;
let queue = [];

export function submitData(data) {
  queue.push(data);

  if (!timer) {
    timer = setTimeout(() => {
      const toSubmit = [...queue];
      queue = [];
      timer = null;

      axios.post('/api/mergeSubmit', toSubmit).then(res => {
        listeners.forEach(cb => cb(res));
      });
    }, 200);
  }
}

export function onResponse(cb) {
  listeners.push(cb);
}

🧩 面试官为什么喜欢这个问题?

因为它能看出你对性能优化、用户体验、系统设计的理解深度

答得好的人,通常会延伸到:

  • 请求合并和节流的本质区别;
  • 合并后的响应如何分发;
  • 服务端怎么解析一批参数;
  • 如何用缓存 + 锁机制做重复提交保护。

而这些,恰恰是中高级前端工程师的分水岭


🧲 面试加分Tips:主动延展“服务端合并解析方案”

面试时我补了一句:

“服务端收到的是一个数组,我们可以在 controller 层拆分每个请求数据,再并发处理,再统一返回。比如可以用 Promise.all 或异步队列去处理每一项请求。这样既能减轻前端负担,又能保持业务一致性。”

面试官点了点头,说了一句:

“你是第一个讲到这一层的人。”


📌 最后的总结

  • 节流和防抖是表层解决方案,适合交互性问题;
  • 请求合并才是架构性的思路,适合多源触发;
  • 能用“合并+分发”的思路解决问题,是前端进阶的关键一步;
  • 大厂面试爱问这种“看似简单,实则有深度”的问题。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大厂面试经(二):前端请求如何将多次提交压缩成一次提交?
    • 🧠 我踩过的一个“高频点击”坑
    • 🚀 把“防抖节流”升维成“请求合并”
    • 💡 解法一:最基础的防抖/节流(适合用户主动操作)
    • 💡 解法二:基于请求缓存的“合并机制”(适合并发场景)
      • 核心思路:
      • 封装代码如下:
    • 💡 解法三:全局事件代理 + 请求合并(适合多个组件并发)
    • 🧩 面试官为什么喜欢这个问题?
    • 🧲 面试加分Tips:主动延展“服务端合并解析方案”
    • 📌 最后的总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档