为了账号安全,请及时绑定邮箱和手机立即绑定

有谁能解释一下Javascript中的“退出”功能吗?

有谁能解释一下Javascript中的“退出”功能吗?

天涯尽头无女友 2019-07-02 09:58:28
有谁能解释一下Javascript中的“退出”功能吗?我对javascript中的“删除”函数感兴趣,它写在这里:http:/davidwalsh.name/javascript-底稿-函数不幸的是,对代码的解释不够清楚,我无法理解。有人能帮我弄清楚它是如何工作的吗(我在下面留下了我的评论)。总之,我真的不明白这是怎么回事   // 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.function debounce(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);     };};编辑:以前复制的代码片段callNow在错误的地方。
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

问题中的代码与链接中的代码略有不同。在链接中,有一个检查(immediate && !timeout)在创建新的超时之前。有了它后,立即模式永远不会开火。我已经更新了我的答案,从链接注释工作版本。


function debounce(func, wait, immediate) {

  // 'private' variable for instance

  // The returned function will be able to reference this due to closure.

  // Each call to the returned function will share this common timer.

  var timeout;


  // Calling debounce returns a new anonymous function

  return function() {

    // reference the context and args for the setTimeout function

    var context = this,

      args = arguments;


    // Should the function be called now? If immediate is true

    //   and not already in a timeout then the answer is: Yes

    var callNow = immediate && !timeout;


    // This is the basic debounce behaviour where you can call this 

    //   function several times, but it will only execute once 

    //   [before or after imposing a delay]. 

    //   Each time the returned function is called, the timer starts over.

    clearTimeout(timeout);


    // Set the new timeout

    timeout = setTimeout(function() {


      // Inside the timeout function, clear the timeout variable

      // which will let the next execution run when in 'immediate' mode

      timeout = null;


      // Check if the function already ran with the immediate flag

      if (!immediate) {

        // Call the original function with apply

        // apply lets you define the 'this' object as well as the arguments 

        //    (both captured before setTimeout)

        func.apply(context, args);

      }

    }, wait);


    // Immediate mode and no wait timer? Execute the function..

    if (callNow) func.apply(context, args);

  }

}


/////////////////////////////////

// DEMO:


function onMouseMove(e){

  console.clear();

  console.log(e.x, e.y);

}


// Define the debounced function

var debouncedMouseMove = debounce(onMouseMove, 50);


// Call the debounced function on every mouse move

window.addEventListener('mousemove', debouncedMouseMove);


查看完整回答
反对 回复 2019-07-02
?
萧十郎

TA贡献1815条经验 获得超13个赞

这里要注意的是debounce产生一个功能被“关闭”的timeout变量。这个timeout变量在生成函数的每次调用过程中保持可访问性,即使在此之后。debounce它已经回来了,而且能,会,可以换不同的电话。

一般想法debounce如下:

  1. 从没有超时开始。
  2. 如果调用所产生的函数,则清除并重置超时。
  3. 如果超时被击中,调用原始函数。

第一点是var timeout;,这确实是undefined..幸运的是,clearTimeout对其输入相当松懈:传递undefined计时器标识符导致它什么也不做,它不会抛出错误或其他东西。

第二点由产生的函数完成。它首先存储有关调用的一些信息(this上下文和arguments)在变量中,以便以后可以将这些用于已取消的调用。然后清除超时(如果有一组),然后使用setTimeout注意,这覆盖了timeout这个值在多个函数调用中持续存在!这就允许退出实际工作:如果函数被多次调用,timeout使用新计时器多次覆盖。如果不是这样,多个调用将导致启动多个计时器保持活跃-这些电话只会被推迟,但不会被取消。

第三点是在超时回调中完成的。它取消了timeout变量,并使用存储的调用信息执行实际函数调用。

这个immediate标志应该控制函数是否应该被调用。以前计时器。如果是的话false,才会调用原始函数。计时器被击中了。如果是的话true,最初的功能是第一被调用,在计时器被击中之前不会再被调用。

不过,我相信if (immediate && !timeout)检查是错误的:timeout返回的计时器标识符。setTimeout所以!timeout总是false在这一点上,因此函数永远不能被调用。当前版本的underscore.js似乎有一个稍微不同的检查,其中评估immediate && !timeout 以前呼叫setTimeout..(算法也有点不同,例如它不使用clearTimeout)这就是为什么您应该始终尝试使用最新版本的库。*-)


查看完整回答
反对 回复 2019-07-02
  • 3 回答
  • 0 关注
  • 549 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信