如何在调用去抖函数之后和执行之前取消该函数
How to cancel a debounced function after it is called and before it executes?
>我创建了一个带有下划线的函数的去抖动版本:
var debouncedThing = _.debounce(thing, 1000);
一旦去抖动的东西被称为...
debouncedThing();
。在实际执行之前的等待期内,有什么方法可以取消它吗?
如果您使用最新版本的 lodash,您可以简单地执行以下操作:
// create debounce
const debouncedThing = _.debounce(thing, 1000);
// execute debounce, it will wait one second before executing thing
debouncedThing();
// will cancel the execution of thing if executed before 1 second
debouncedThing.cancel()
另一种解决方案是使用标志:
// create the flag
let executeThing = true;
const thing = () => {
// use flag to allow execution cancelling
if (!executeThing) return false;
...
};
// create debounce
const debouncedThing = _.debounce(thing, 1000);
// execute debounce, it will wait one second before executing thing
debouncedThing();
// it will prevent to execute thing content
executeThing = false;
文档(我现在正在查看 1.9.1)说您应该能够做到:
var fn = () => { console.log('run'); };
var db = _.debounce(fn, 1000);
db();
db.cancel();
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.6/underscore-umd-min.js"></script>
这将做 OP 想要做的事情(以及我想做的事情)。它不会打印控制台消息。
对于其他使用 React 和状态钩子的人。将去抖动事件包装在 ref 中,然后访问其他地方:
const [textInputValue, setTextInputValue] = React.useState<string>('')
const debouncedSearch = React.useRef(
debounce((textInputValue) => {
performSearch(textInputValue)
}, 300),
).current
React.useEffect(() => {
// cancel any previous debounce action (so that a slower - but later - request doesn't overtake a newer but faster request)
debouncedSearch.cancel()
if (textInputValue !== '') {
debouncedSearch(textInputValue)
}
}, [textInputValue])
带有
可取消包装的香草js变体
请注意,此解决方案不需要修改外部debounce
函数,甚至不需要使用外部函数。该逻辑在 wrapepr 函数中完成。提供去抖码。
允许在其去抖动期内取消已调用函数的最简单方法是从可取消包装中调用它。实际上只需添加 3 行代码和一个可选条件。
const doTheThingAfterADelayCancellable = debounce((filter, abort) => {
if (abort) return
// here goes your code...
// or call the original function here
}, /*debounce delay*/500)
function onFilterChange(filter) {
let abort = false
if (filter.length < 3) { // your abort condition
abort = true
}
// doTheThingAfterADelay(filter) // before
doTheThingAfterADelayCancellable(filter, abort) // new wrapped debounced call
}
您可以通过再次调用它来取消它 abort = true
.
它的工作方式是清除以前的超时 fn 并像往常一样设置一个新的超时 fn,但现在有了if (true) return
路径。
您也可以从另一个代码手动执行此操作...
doTheThingAfterADelayCancellable(null, true)
。或将其包装起来并与cancelBounce()
通话
function cancelBounce() {
doTheThingAfterADelayCancellable(null, true)
}
作为参考,这是您从
Underscore
中获取的经典debounce
函数。在我的示例中,它保持不变。// taken from Underscore.js // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. export function debounce(func, wait, immediate) { let timeout return function() { let context = this, args = arguments let later = function() { timeout = null if (!immediate) func.apply(context, args) } let callNow = immediate && !timeout clearTimeout(timeout) timeout = setTimeout(later, wait) if (callNow) func.apply(context, args) } }
我所做的是使用 _.mixin 创建一个 _.cancellableDebounce 方法。 除了两行新行外,它几乎与原版相同。
_.mixin({
cancellableDebounce: function(func, wait, immediate) {
var timeout, args, context, timestamp, result;
var later = function() {
var last = _.now() - timestamp;
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function() {
context = this;
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
// Return timeout so debounced function can be cancelled
result = result || {};
result.timeout = timeout;
return result;
};
}
});
用法:
var thing = function() {
console.log("hello world");
}
var debouncedThing = _.cancellableDebounce(thing, 1000);
var timeout = debouncedThing().timeout;
clearTimeout(timeout);
相关文章:
- 等待回调函数执行
- 暂停函数执行流程,直到ajax请求完成
- Bigcommerce-是否可以在函数执行后更改文本
- 如何对jquery中的未命名函数执行.call()
- 等待函数执行后再继续
- mootools类型的函数将文本作为函数执行
- 停止从另一个函数执行Javascript函数
- Jquery回调函数执行多次
- 如何使即兴 jquery 暂停当前函数执行
- JavaScript 双函数执行
- 来自函数 Javascript 的 NaN 返回值 ||函数执行顺序
- 如何在 JS 中调用 2 次或更多次时延迟函数执行
- 函数执行的次数超出预期
- JS中函数执行错误
- 为什么这个函数执行了两次
- 从子函数执行父函数;t更新父级'的属性
- 如何在jQuery函数执行's处于活动状态
- 使用javascript函数执行php文件
- jQuery函数执行顺序
- javascript中同步函数执行中的问题