gpt4 book ai didi

JavaScript 通用异步/等待 "debounce"

转载 作者:行者123 更新时间:2023-12-01 01:35:13 25 4
gpt4 key购买 nike

所以基本上我有一个异步事件回调,有时会很快触发。我想做的是立即执行一些方法,但然后等到最后一次偶数调用后一段时间,然后再执行代码的最后一点。

这是一个例子:

let debounceTimeout
async function onEvent() {
// do stuff here on every event

const waitTime = 5000
await new Promise(resolve => {
clearTimeout(debounceTimeout)
debounceTimeout = setTimeout(resolve, waitTime)
})

// do stuff here only on the last event after waiting for "waitTime"
}

所以上面的例子完全按照我想要的方式工作,但是,对于敏锐的眼睛,您可能会意识到最终事件之前的所有事情都被无限期地“等待”,这(我假设)是内存泄漏,因为它会不断创建新的永远无法兑现的 promise 。

基本上我想知道是否有任何通用的方法可以进行功能相同但没有内存泄漏的谴责。如果可以以某种方式将其清理为简单的 await debounce(timeInMS) 调用,则可获得加分。

附注我在想也许一些类似于拒绝超时的事情永远不会解决,但我不确定这是否是一个好方法。

附注我知道我所要求的可以通过跟踪事件并检查在等待 5 秒后是否发生了新事件来有效地完成,如果我需要这样做,那就这样吧。也就是说,这将是我正在开发的应用程序中的常见模式,我想要一些更简洁的东西,并希望这个想法不会太过分。

最佳答案

对于这个用例, promise 并不是理想的机制:

  1. 事件触发代码通常不期望返回 promise 。它只是广播。

  2. 当新事件在等待时间到期之前到达时,您需要“取消” promise 。您可以通过解决或拒绝该特定 promise 来做到这一点,但您仍然必须将该结果与该 promise 的正常解决方案区分开来。所需的代码似乎不太优雅。但我会让你来判断(见下文)

  3. setTimeout 本身似乎已经足够好了

下面是同一演示的两个替代方案。它以随机间隔触发事件。输出为每一个都显示一个点。当等待超时在下一个事件到来之前到期时,将在输出中开始一个新行:

使用 Promise 进行演示

const waitTime = 700;

async function onEvent() {
// do stuff here on every event
log.textContent = "." + log.textContent;

if (onEvent.resolve) onEvent.resolve(true);

if (await new Promise(resolve => {
onEvent.resolve = resolve; // Get a handle to resolve this promise preemptively
setTimeout(resolve, waitTime);
})) return; // Promise was resolved before timeout happened

// Do stuff here only on the last event after waiting for "waitTime"
log.textContent = "\n" + log.textContent.replace(/\n|$/, "completed\n");
}

// Demo
setRandomInterval(onEvent, 1, 1000);

// Utility function for triggering an event at irregular intervals
function setRandomInterval(cb, min, max) {
let timeout = setTimeout(() => {
cb();
timeout = setRandomInterval(cb, min, max);
}, min + Math.random()*(max-min));
return () => clearTimeout(timeout);
}
<pre id="log"></pre>

没有 promise 的演示

const waitTime = 700;

function onEvent() {
// do stuff here on every event
log.textContent = "." + log.textContent;

clearTimeout(onEvent.debounceTimeout);
onEvent.debounceTimeout = setTimeout(() => {
// Do stuff here only on the last event after waiting for "waitTime"
log.textContent = "\n" + log.textContent.replace(/\n|$/, "completed\n");
}, waitTime);
}

// Demo
setRandomInterval(onEvent, 1, 1000);

// Utility function for triggering an event at irregular intervals
function setRandomInterval(cb, min, max) {
let timeout = setTimeout(() => {
cb();
timeout = setRandomInterval(cb, min, max);
}, min + Math.random()*(max-min));
return () => clearTimeout(timeout);
}
<pre id="log"></pre>

关于JavaScript 通用异步/等待 "debounce",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52892333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com