使用参数去抖动函数

时间:2015-02-28 21:59:37

标签: javascript underscore.js lodash

我正在尝试debounce一个save函数,该函数将对象保存为在击键时触发的自动保存的参数。去抖动会阻止保存发生,直到用户停止输入,或者至少是这个想法。类似的东西:

var save = _.debounce(function(obj) {
  ... 
}, delay);

如果我试图快速连续保存两个物体,那么这会分崩离析。因为debounce没有考虑传入的对象,所以只会激活第二次save来调用,只保存一个对象。

save(obj1);
save(obj2);

仅保存obj2,例如。

我可以使obj一个类的实例具有自己的save方法,该方法负责将保存仅对该对象进行去除。或者在某处保留部分/咖喱功能列表,但我希望那里有一站式解决方案。类似的东西:

var save = _.easySolution(function(obj) {
  ... 
}, delay);

我正在寻找以下保存每个对象的保存字符串,但只保存每个对象一次。

save(obj1);
save(obj2);
save(obj3);
save(obj2);
save(obj2);
save(obj3);
save(obj2);
save(obj1);

编辑:这样的事情,也许,只是不那么复杂,以及不会使obj函数变异__save的东西?

function save(obj) {
  if(!obj.__save) {
    obj.__save = _.debounce(_.partial(function(obj) {
      ...
    }, obj), delay);
  }

  obj.__save();
}

3 个答案:

答案 0 :(得分:15)

您将要为每个传递的参数创建一个去抖动函数版本。您可以使用debounce()memoize()wrap()轻松完成此操作:

function save(obj) {
    console.log('saving', obj.name);
}

var saveDebounced = _.wrap(_.memoize(function() {
    return _.debounce(save);
}, _.property('id')), function(func, obj) {
    return func(obj)(obj);
});

saveDebounced({ id: 1, name: 'Jim' });
saveDebounced({ id: 2, name: 'Jane' });
saveDebounced({ id: 1, name: 'James' });
// → saving James
// → saving Jane

您可以看到'Jim'未被保存,因为具有相同ID的对象会立即保存。 saveDebounced()功能细分如下。

_memoize()的调用是根据某些解析程序功能缓存去抖动函数。在此示例中,我们只是将其基于id属性。所以现在我们有办法为任何给定的参数获得save()的去抖动版本。这是最重要的部分,因为debounce()具有各种内部状态,因此我们需要为可能传递给save()的任何参数提供此函数的唯一实例。

我们正在使用wrap()来调用缓存的函数(或创建它然后缓存它,如果它是第一次调用),并传递函数我们的对象。生成的saveDebounced()函数与save()具有完全相同的签名。区别在于saveDebounced()将根据参数去抖动调用。

答案 1 :(得分:0)

可能是这样的:

var previouslySeen = {}

var save = _.debounce(function(obj) {
  var key = JSON.stringify(obj);
  if (!previouslySeen[key]) {
     previouslySeen[key] = 1;
  } else {
     ...
  }
}, delay);

答案 2 :(得分:0)

您可以在闭包中使用内部对象来设置/获取去抖动功能。

在此示例中,我们在调用debounced函数的同时检查是否已将带有此args的args的debounced函数保存在我们的memory对象中。如果没有-我们创建它。

const getDebouncedByType = (func, wait, options) => {
  const memory = {};

  return (...args) => {
    // use first argument as a key
    // its possible to use all args as a key - e.g JSON.stringify(args) or hash(args)
    const [type] = args;

    if (typeof memory[searchType] === 'function') {
      return memory[searchType](...args);
    }

    memory[searchType] = debounce(func, wait, { ...options, leading: true }); // leading required for return promise
    return memory[searchType](...args);
  };
}; 

原始要点-https://gist.github.com/nzvtrk/1a444cdf6a86a5a6e6d6a34f0db19065