返回
一键搞定 Promise 重复回调问题
前端
2023-10-05 18:51:28
Promise 回调重复调用的原因
在 JavaScript 中,Promise 是一个对象,它表示一个异步操作的最终完成或失败。当我们调用 Promise 的 then()
或 catch()
方法时,我们指定了一个回调函数,该函数将在 Promise 完成或失败时被调用。
通常情况下,回调函数只会被调用一次。但是,在某些情况下,回调函数可能会被重复调用。例如,如果我们在用户快速点击刷新按钮后,短时间内会有多个网络请求发出,那么这些请求的回调函数可能会被重复调用。
简单粗暴地防止回调函数被重复调用
为了防止回调函数被重复调用,我们可以使用一个简单的技巧。每次我们调用 Promise 的 then()
或 catch()
方法时,我们都保存当前的上下文环境(例如,当前时间戳)。然后,当我们接到返回的时候,我们判断一下当前的时间戳是否与保存的时间戳相同。如果不同,则说明该回调函数是由于之前的请求而被调用的,我们可以忽略它。
const makeRequest = () => {
// 保存当前的时间戳
const timestamp = Date.now();
// 调用 Promise 的 then() 方法
return fetch('https://example.com')
.then(response => {
// 判断当前的时间戳是否与保存的时间戳相同
if (timestamp !== Date.now()) {
// 如果不同,则忽略该回调函数
return;
}
// 如果相同,则处理请求的返回结果
return response.json();
});
};
使用唯一标识来解决重复回调问题
除了使用上述技巧之外,我们还可以使用唯一标识来解决重复回调问题的。每次我们调用 Promise 的 then()
或 catch()
方法时,我们都生成一个唯一的标识。然后,当我们接到返回的时候,我们判断一下该唯一标识是否已经存在。如果存在,则说明该回调函数是由于之前的请求而被调用的,我们可以忽略它。
const makeRequest = () => {
// 生成一个唯一的标识
const requestId = Math.random().toString(36).substring(7);
// 调用 Promise 的 then() 方法
return fetch('https://example.com')
.then(response => {
// 判断该唯一标识是否已经存在
if (requestId !== requestIdMap[response.url]) {
// 如果存在,则忽略该回调函数
return;
}
// 如果不存在,则处理请求的返回结果
return response.json();
});
};
总结
在 JavaScript 中,Promise 回调重复调用的问题可能会导致页面刷新多次或其他意外行为。我们可以使用一种简单粗暴的方法来防止回调函数被重复调用,也可以使用唯一标识来解决该问题。