【问题标题】:Debounce values but return all non unique elements instead of just one element in javascript [duplicate]去抖值但返回所有非唯一元素,而不是javascript中的一个元素[重复]
【发布时间】:2022-02-17 00:36:43
【问题描述】:

我有一个用例,我有多个函数同时触发。 每个函数都可以调用多次,但我只需要选择一个返回值。我正在使用 debounce,它确实按预期工作。即使我有 10 个返回值,最后我也只能得到 1 个返回值。但是,如果有唯一值,我希望返回所有唯一值

发生了什么

-----1----2-----2---2----2----2----3-----3---3---3---3---3------>
(Only 1 value is returned)
-------------------3--------------------------------------------->

我想要什么

-----1----2-----2----2----2----2----3-----3---3---3---3---3------>
(Return all unique values)
-------------------1-------------------2--------------------3---->

我尝试过的(示例)

var _ = require('lodash');

function printOne () {
  handleDebounce(1);
}

function printTwo () {
  handleDebounce(2);
}

function printThree () {
  handleDebounce(3);
}


const handleDebounce = _.debounce((msg) => {
  console.log(msg)
}, 2000, );


printOne();
printTwo();
printTwo();
printTwo();
printThree();
printThree();
printThree();

输出 -> 3

预期输出 -> 1 2 3

我是否应该使用一个集合来获得某种形式的本地缓存,然后获取唯一值?欢迎任何指点

【问题讨论】:

  • 如果你用 1 - 2 - 2 - 3 - 1 - 2 - 2 - 3 喂它怎么办?输出应该是什么?
  • @trincot 这个想法是在这里只获得独特的元素。所以在上面的情况下,输出应该是 -> 1 2 3 (只有唯一的元素,排序无关紧要)
  • Ivar 指向的链接能否解决您的问题?
  • 通话之间有延迟的要求吗?就像如果你有 1-2-3-4-5-6 快速连续,那么所有 6 个呼叫是否应该在两个连续呼叫之间有延迟时间?这不会是“去抖动”,而是延迟执行可能很长的累积时间......或者应该像默认行为一样跳过一些?还是第一次延迟后延迟为0?
  • @trincot 不管打了多少电话..每个电话都保证快速返回。无论每个值返回多少次,期望只是获得唯一值。

标签: javascript asynchronous lodash debounce


【解决方案1】:

您可以跟踪传递给函数的所有参数。您可以在嵌套查找 Map 中执行此操作,其中每个嵌套级别都与下一个参数有关(如果传递了多个参数)。一个特殊的结束符号表示嵌套 Map 中的一个参数是最后一个参数 - 以区分传递相同参数但后面有一些额外参数的情况。

这是如何实现的:

function withUniqueArguments(func, delay=50) {
    const end = Symbol("end"); // A unique value only known here
    const map = new Map; // Stores all argument references used before
    
    function testAndSetArgs(args) {
        let node = map;
        for (const arg of args) {
            let res = node.get(arg);
            if (res === undefined) node.set(arg, res = new Map);
            node = res;
        }
        let found = node.get(end);
        if (!found) node.set(end, true);
        return !!found;
    }
    
    return function wrapper(...args) {
        if (testAndSetArgs(args)) return; // Function was called with these arguments before
        setTimeout(() => func.call(this, ...args), delay);
    };
}

const handleSearch = withUniqueArguments(console.log, 50);

handleSearch(1);
handleSearch(2);
handleSearch(2);
handleSearch(2);
handleSearch(3);
handleSearch(3);
handleSearch(3);

免责声明:参数的比较是基于引用的,因此如果将对象作为参数传递,则只有当它们确实是同一个对象时才会被视为相同,而不是它们的副本。此外,当一个对象在调用之间发生变异,并作为参数再次传递时,它仍将被视为同一个对象,因此不会进行第二次调用。

如果您需要将复制的对象视为相同,而将变异的对象视为不同,那么您需要包含一个深度对象比较函数。

【讨论】:

  • 谢谢!这有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 2010-11-12
  • 2014-12-16
相关资源
最近更新 更多