如何在一个函数中创建setTimeOut并在另一个函数中将其销毁



我试图做一些类似于谷歌文档的事情。这是一个自动保存系统/循环。我将在几秒钟不活动后保存一个文档(通过从类中调用save方法(。

如果在这几秒钟内有一些活动,那么我将重置/延长计时器几秒钟。这个循环将一直持续到调用save方法,其中我将中断循环并等待另一个活动再次启动循环。

下面是我想出的一些伪代码:

doc.on('mouse:up', (event) => {
... //<--- Initialize the timer on mouse:up event
... //<--- When time is up, execute the save method
})
doc.on('mouse:down', (event) => {
... //<--- prolong timer initialized in the mouse:up event if it is available.
}

然而,我认为这种方式是不可能的,因为我无法访问相同的初始化setTimeOut对象。有没有一个好的方法来实现这一点?很想听听雅尔的意见。

有几种方法可以处理此问题。

方法:基本
缺点:级别低,行为不那么明显。

const saveDelayMs = 1000;
let timeoutId;
doc.on('mouse:up', (event) => {
timeoutId = setTimeout(save, saveDelayMs);
});
doc.on('mouse:down', (event) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(save, saveDelayMs);
}

方法:去抖动抽象
优点:级别更高,代码更可读

// Trigger 1000ms after last call
const debouncedSave = debounce(save, 1000);
doc.on('mouse:up', (event) => {
debouncedSave();
});
doc.on('mouse:down', (event) => {
debouncedSave();
});
function debounce(fn, debounceDelayMs) {
let timeoutId;

return () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(fn, debounceDelayMs);
};
});

Lodash提供了一个防反弹功能,我建议您不要创建自己的功能。

只需在两个函数之外初始化变量。这样,它将可以在其中任何一个内部访问:

let theTimeout = null;
doc.on('mouse:up', (event) => {
theTimeout = setTimeout(...); //<--- Initialize the timer on mouse:up event
})
doc.on('mouse:down', (event) => {
clearTimeout(theTimeout);
theTimeout = setTimeout(...); //<--- prolong timer initialized in the mouse:up event if it is available.
}

您可以使用去抖动方法(请参阅此处:https://davidwalsh.name/javascript-debounce-function),但如果您要查看多种类型的输入(例如,拖动对象停止保存,但也停止触摸和指针等(,则可能是最清晰的。最好使用全局标志,并使用它从代码中的任何位置切换保存标志,这样任何人都可以触发保存建议:

let saveFlag = false;
setInterval(function(){

if( saveFlag === true ){

console.log( 'save' );
saveFlag = false;

} else {

console.log( 'skip save' );

}

}, 3000);
// Now you can trigger a save on any kind of event,
// and expect it to happen within 3 seconds.
document.addEventListener( 'click', e => saveFlag = true);
document.addEventListener( 'touchend', e => saveFlag = true);
document.addEventListener( 'pointerup', e => saveFlag = true);

这也将防止可能创建重复的定时器,并且在我的示例中具有最大延迟或3000ms,开销非常小。

最新更新