首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript脱附函数

JavaScript脱附函数
EN

Code Review用户
提问于 2018-07-04 05:53:11
回答 1查看 255关注 0票数 1

我构建了一个JavaScript卸载函数。如果这是正确的方法,我需要一个JavaScript专家的意见,如果不是,那么这个当前函数的缺陷是什么。

代码语言:javascript
复制
var debounce = function(inpFun, wait) {
    var timeout;
    return function () {
        if(!timeout) {
            inpFun.apply(this, arguments);
            timeout = setTimeout(function() {
                timeout = undefined;
            }, wait);
        }
        else {
            console.log("Debouncing");
        }
    }
};

var buttonClickFunction = debounce(function (event) {
    console.log("Button Clicked");
    console.log(event.target.id);
}, 2000);



document.querySelector("#button1").addEventListener("click", buttonClickFunction);
EN

回答 1

Code Review用户

回答已采纳

发布于 2018-07-04 12:09:11

事件速率限制器

在定义函数时使用正确的术语是很重要的。如果你不确定,最好是查阅文献,以确保你正确地使用了这个词。

脱轨

你还没有实现反反弹。反反弹推迟了对某一事件的行动,以防止其迅速连续开火.

这个术语来自于你以前的硬件,在这种硬件中,机械开关会在触点上产生反弹的倾向,在只有一个开关的时候会发出一系列的开关信号。

在Javascript中,我们使用去弹来防止以高速率(如鼠标调整大小)触发的事件以比有用的更高的频率(例如屏幕刷新率)触发。

您可以按以下方式实现反跳

代码语言:javascript
复制
const debounce = {
    debounceTime : 33, // in ms
    timeoutHandle : undefined,
    ondebounced(event) {
        log("Resized");
    },
    event(event) {
        clearTimeout(debounce.timeoutHandle);
        debounce.timeoutHandle = setTimeout(debounce.ondebounced, debounce.debounceTime, event)
    }
}
addEventListener("resize",debounce.event);

在最后一次调整大小事件之后,它将等待33 de,然后调用去反弹函数。

速率限制器

您已经实现了一个速率限制器,它强制一个事件以设定的最大速率触发。差别很小,

  • 在事件发生后(信号噪声)会发生反弹,而限速器则会尽快开火.
  • 去弹跳延迟是不确定的,而速率限制有固定的确定延迟.

您的代码

你的密码有点老套。您应该跟上lates版本的ES8。

  • 当您希望变量不改变时,您应该使用const
  • 使用箭头函数。
  • 使用spread / rest令牌传递未知参数。见示例

您还混合了变量的用法。变量timeout.这目前可能不会给您带来麻烦,而且通过加倍变量(意为timeoutHandle和Block )来减少代码大小似乎是个不错的主意,但是如果将来您做了更改而忘记了timeout不仅仅是一个句柄,这就会产生影响。

不要混淆变量的含义,而不让它在名称中明确。

示例

下面是如何实现速率限制器的示例。

该功能是封装的,访问只能通过getter和setter进行,以防止错过使用。更多信息见评论。这只是一个例子,而不是一个明确的方法。

代码语言:javascript
复制
    // Encapsulated rateLimit event utility
    const rateLimit = (()=>{
        const rate = 2000;  // the max rate in ms
        
        // the limiting functions, pass the event to call
        // returns an API for handling the events.
        return function (eventFunc){
            var handle;  // for unblock event
            var blocked = false;  // true if blocked
            var event;  // the event to call if not blocked
            // this function handles the incoming event
            const eventHandler = (...eventArgs) => {
                if(blocked){
                    log("Event blocked. Too fast.")
                }else{
                    API.block = true;
                    if (event) { event(...eventArgs) }
                }
            }
               
            // the API 
            // block bool (write only) set to true will block events for
            // rate but only if not already blocked. Set to false to clear any blocking
            // blocked returns (read only) bool for current blocking state
            // onlimitedevent  read/write function to call on event. If not a function then clears the event
            // event read only gets the event to attach to the listener
            const API = {
                set block(value) {
                    if (value && !blocked) { 
                        handle = setTimeout(()=>API.block = false, rate);
                        blocked = true;
                    } else if (!value && blocked) { 
                        clearTimeout(handle); // incase unblock is from outside
                        blocked = false 
                    
                    }
                },
                get blocked() { return blocked },
                set onlimitedevent(func) { event = typeof func === "function"  ? func : undefined },
                get onlimitedevent() { return event },
                get event() { return eventHandler },
        

            }
            API.onlimitedevent = eventFunc;
            return API;
        };
        
    })();

    const clicker = rateLimit(() => {log("clicked")});
    document.body.addEventListener("click", clicker.event);
    log("Ready, click me to test.");

    function log(...data) { out.appendChild(Object.assign(document.createElement("div"),{textContent : data.toString()})) }
代码语言:javascript
复制
<code id="out"></code>
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/197772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档