如何从限制函数中获取最后一个值

时间:2016-04-18 15:21:31

标签: javascript lodash

_.throttle函数的文档说明:

  

创建一个限制函数,每次最多只调用一次func   每等待几毫秒。限制功能带有取消功能   取消延迟的func调用和flush方法的方法   立即调用它们。提供选项对​​象以指示是否   应该在等待的前沿和/或后沿调用func   超时。使用提供给的最后一个参数调用func   节流功能。后续调用throttled函数返回   最后一次func调用的结果

我对这一行感兴趣:

  

后续调用throttled函数返回   最后一次func调用的结果

我试过了:

julia_function()

问题是var throttled = _.throttle(updateModelData, 1000); service.on('change', function () { throttled(5); }); function updateModelData(data) { // all calls here log 5's console.log(data); return data; } setTimeout(function() { throttled(); // here updateModelData is executed with `undefined` value }, 5000); 触发函数而不返回数据。如何调用它以便返回最后的数据?

编辑:

根据源代码,仅当没有待处理的函数调用throttled()时,才会返回该值:

isCalled === false

以下内容将起作用:

  function debounced() {
    args = arguments;
    stamp = now();
    thisArg = this;
    trailingCall = trailing && (timeoutId || !leading);

    if (maxWait === false) {
      var leadingCall = leading && !timeoutId;
    } else {
      if (!maxTimeoutId && !leading) {
        lastCalled = stamp;
      }
      var remaining = maxWait - (stamp - lastCalled),
          isCalled = remaining <= 0 || remaining > maxWait;

      !!!!! HERE
      if (isCalled) {
        if (maxTimeoutId) {
          maxTimeoutId = clearTimeout(maxTimeoutId);
        }
        lastCalled = stamp;
        result = func.apply(thisArg, args);
      }
      else if (!maxTimeoutId) {
        maxTimeoutId = setTimeout(maxDelayed, remaining);
      }
    }
    ...
    return result;
  }

2 个答案:

答案 0 :(得分:1)

以下代码可以正常使用:

var throttled = _.throttle(updateModelData, 1000);
var i = 0;

function updateModelData(data) {
    return data;
}

var interval = setInterval(function() {
    console.log(throttled(i++));

    if (i === 6) {
        clearInterval(interval);
        console.log('Last value: ' + throttled());
    }
}, 2000);

输出:

0
1
2
3
4
5
"Last value: 5"

DEMO

答案 1 :(得分:1)

问题在于,当您有前导调用(_.throttle的默认行为)时,当您第一次调用受限制的函数时(或者在您的延迟时间过去之后首先调用它),它会立即调用底层调用在返回任何东西之前的功能。

这意味着“最后一次函数调用的结果”可能是由当前调用限制函数引起的函数调用的结果。因此,您调用throttle()调用updateModelData()然后返回undefined,因为updateModelData()返回undefined。

以下是一些示例代码,可能会澄清这一点:

var foo = (x) => x;
var leading = _.throttle(foo, DELAY, {leading: true, trailing: false}); //these are the default options for leading and trailing
var trailing = _.throttle(foo, DELAY, {leading: false, trailing: true});

leading(1); //Calls foo(1), returns 1
leading(2); //Doesn't call foo, returns 1, 
leading(3); //Doesn't call foo, returns 1

trailing(1); //Doesn't call foo, returns undefined
trailing(2); //Doesn't call foo, returns undefined

//DELAY ms later
//foo(2) is called, due to the most recent call to bar2

leading();  //Calls foo(), returns undefined 
leading(1); //Still returns undefined from above

trailing(); //Doesn't call foo, returns 2
trailing(1); //Doesn't call foo, returns 2

//Another DELAY ms later

leading("Whatever"); //Calls foo("Whatever"), returns "Whatever";

以下是您JSFiddle的一个版本,使其更加明显。

实际上,你不应该只是为了获取它返回的最后一个值来调用函数,所以我建议你自己管理最后一个值,而不是依靠_.throttle来为你做。例如:

var lastResultOfFoo;
var foo = function (x) {
    lastResultOfFoo = x;
    return x;
}

//OR (if you don't mind attaching arbitrary properties to functions)
var foo = function (x) {
    foo.lastResult = x;
    return x;
}