前言
胖头鱼最近在整理一些以往亲身经历的
面试真题
时,发现了一道很有意思的题目,来自蚂蚁金服
某次在线笔试。如何防止重复发送请求? 有没有发现平时的业务也会有类似的场景需要处理?看来蚂
真题再现
问题:业务需求中,经常有只需要请求一次,以防止用户重复点击行为导致触发重复请求。
传递请求方法(执行后返回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
执行的回调复用这一个请求的结果,那么实现就很简单啦!可以将请求的实例先存储起来,而成功和失败内部都可以感知到,进而将其重新置空,接受下一次请求。
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);
可以看到虽然我们调用了firstFn
6次,但是实际请求只发生了两次(因为count只由1变成了2),恭喜,蚂蚁的笔试题你通过了。