蚂蚁金服在线笔试:如何防止重复发送请求?

2022-07-25 08:42:26 浏览数 (1)

前言

胖头鱼最近在整理一些以往亲身经历的面试真题时,发现了一道很有意思的题目,来自蚂蚁金服某次在线笔试。如何防止重复发送请求? 有没有发现平时的业务也会有类似的场景需要处理?看来蚂

真题再现

问题:业务需求中,经常有只需要请求一次,以防止用户重复点击行为导致触发重复请求。

传递请求方法(执行后返回promise),返回一个新方法。连续触发时,只执行一次。

代码语言:javascript复制

// 示例
let count = 1;
let promiseFunction = () =>
  new Promise(rs =>
    window.setTimeout(() => {
      rs(count  );
    })
  );
let firstFn = firstPromise(promiseFunction);
firstFn().then(console.log); // 1
firstFn().then(console.log); // 1
firstFn().then(console.log); // 1

解析

题目的原意是阻止重复发送请求firstFn执行的回调复用这一个请求的结果,那么实现就很简单啦!可以将请求的实例先存储起来,而成功和失败内部都可以感知到,进而将其重新置空,接受下一次请求。

代码语言:javascript复制

function firstPromise(promiseFunction) {
  let p = null;
  return function (...args) {
    // 请求的实例,已存在意味着正在请求中,直接返回实例,不触发新的请求
    return p
      ? p
      // 否则发送请求,且在finally时将p置空,那么下一次请求可以重新发起
      : (p = promiseFunction.apply(this, args).finally(() => (p = null)));
  };
}

测试一下

代码语言:javascript复制
let count = 1;
let promiseFunction = () =>
  new Promise((rs) =>
    setTimeout(() => {
      rs(count  );
    }, 1000)
  );
let firstFn = firstPromise(promiseFunction);
firstFn().then(console.log); // 1
firstFn().then(console.log); // 1
firstFn().then(console.log); // 1

setTimeout(() => {
  firstFn().then(console.log); // 2
  firstFn().then(console.log); // 2
  firstFn().then(console.log); // 2
}, 3000);

可以看到虽然我们调用了firstFn6次,但是实际请求只发生了两次(因为count只由1变成了2),恭喜,蚂蚁的笔试题你通过了。

0 人点赞