如何在调用之后和执行之前取消去抖动函数?

时间:2015-03-12 14:48:14

标签: javascript underscore.js

我使用下划线创建了一个去抖动函数:

var debouncedThing = _.debounce(thing, 1000);

一旦调出debouncedThing ......

debouncedThing();

...有没有办法在实际执行之前的等待期间取消它?

4 个答案:

答案 0 :(得分:40)

如果您使用最后一个版本的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 :(得分:1)

我所做的是使用_.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);

答案 2 :(得分:0)

在其去抖动期间取消已调用函数的最简单方法是使其可取消。真的只需添加3行代码和一个条件。

const doTheThingAfterADelay = debounce((filter, abort) => {
  if (abort) return

  // here goes your code...

}, /*debounce delay*/500)


function onFilterChange(filter) {
  let abort = false

  if (filter.length < 3) { // your abort condition
    abort = true
  }

  doTheThingAfterADelay(filter, abort) // debounced call
}

您可以使用abort = true再次调用来取消它。

  

供参考,这是您从debounce获取的经典Underscore函数。它在我的例子中保持不变。

// 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)
  }
}

答案 3 :(得分:0)

很老,但是给到达这里的其他人加了一条便条。

文档(我现在正在查看1.9.1)说您应该可以:

var fn = () => { console.log('run'); };
var db = _.debounce(fn, 1000);
db();
db.cancel();

这将完成OP想要做的事情(以及我想做的事情)。它不会打印控制台消息。

我从来没有能够做到这一点。我已经按照《底线》文档中的承诺.cancel()高低在上,但找不到。

如果使用的是下划线,请在Carlos Ruana接受的答案中使用标记选项。可悲的是,我的要求(我认为)不允许从Underscore升级到Lodash。下划线功能较少,但功能要比没有底线更多。