我在网上找到了一个很棒的debounce()
函数代码,但是我很难将它从 ES5 转换为 ES6。
问题如下:当我使用 ES5 实现时,一切正常。调整窗口大小,console.log()
立即 被触发,随后的大小调整将被忽略,直到我指定的 500 毫秒之后。
然而,在 ES6 实现中,第一次调用会立即生效...但之后的每次调用都会延迟 500 毫秒,即使在冷却之后也是如此!
如果有人知道我做错了什么,我将不胜感激。
例子:
function debounceES5(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const debounceES6 = (callback, wait, immediate=false) => {
let timeout = null
return (...args) => {
const callNow = immediate && !timeout
const next = () => callback(...args)
clearTimeout(timeout)
timeout = setTimeout(next, wait)
if (callNow) { next() }
}
}
document.querySelector('.es5').addEventListener('click', debounceES5(() => {console.log('clicked')}, 1000, true))
document.querySelector('.es6').addEventListener('click', debounceES6(() => {console.log('clicked')}, 1000, true))
Click both of these buttons fast and see how they react differently
<br />
<button class="es5">ES5</button>
<button class="es6">ES6</button>
最佳答案
这是用 ES6 编写的 ES5 函数 - 没有跳过任何细节(不相关的 context
除外)
const debounce = (func, wait, immediate=false) => {
let timeout;
return (...args) => {
const later = () => {
timeout = null; // added this to set same behaviour as ES5
if (!immediate) func(...args); // this is called conditionally, just like in the ES5 version
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func(...args);
};
};
请注意,later
函数的作用与 ES5 版本完全相同
这现在应该(几乎)与 ES5 版本的行为相同......整个 context = this
事情 在 ES5 版本中似乎完全奇怪 对示例有意义用法
However, as per comments, since the code is used for event handler,
this
is quite important, it's the Event Target so, you really can't return anarrow function
更好的代码应该是
const debounce = (func, wait, immediate=false) => {
let timeout;
return function (...args) {
const later = () => {
timeout = null; // added this to set same behaviour as ES5
if (!immediate) func.apply(this, args); // this is called conditionally, just like in the ES5 version
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
};
关于javascript - 无法将 Debounce ES5 转换为 ES6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56013445/