Javascript 如何从节流函数中获取最后一个值
函数的文档说明: 创建一个受限制的函数,该函数每次最多只调用一次func 每等待一毫秒。throttled函数带有一个cancel 方法取消延迟的func调用,并使用flush方法取消延迟的func调用 立即调用它们。提供一个选项对象以指示 应在等待的前缘和/或后缘调用func 超时。将使用提供给的最后一个参数调用func 节流功能。对节流函数的后续调用返回 上次func调用的结果 我对这一行很感兴趣: 对节流函数的后续调用返回 上次func调用的结果 我试过:Javascript 如何从节流函数中获取最后一个值,javascript,lodash,Javascript,Lodash,函数的文档说明: 创建一个受限制的函数,该函数每次最多只调用一次func 每等待一毫秒。throttled函数带有一个cancel 方法取消延迟的func调用,并使用flush方法取消延迟的func调用 立即调用它们。提供一个选项对象以指示 应在等待的前缘和/或后缘调用func 超时。将使用提供给的最后一个参数调用func 节流功能。对节流函数的后续调用返回 上次func调用的结果 我对这一行很感兴趣: 对节流函数的后续调用返回 上次func调用的结果 我试过: var throttled =
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;
}
以下代码可以正常工作:
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"
问题在于,当您有前导调用时(
\uu0.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";
这里有一个版本的你的,使它稍微更明显了
实际上,你不应该仅仅为了获取函数返回的最后一个值而调用函数,所以我建议你自己管理最后一个值,而不是依赖于
\uu.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;
}
什么是
this.getData
?@elclanrs,我已经从示例中删除了this.getData()
,现在应该很清楚了,看一看please@Maximus从节流函数返回的值保存在何处?@Neal,我不知道,该值存储在lodash的debounce
函数中。是的,正在工作,但是稍后尝试通过调用throttled()
获取最新的值是的,谢谢你的努力,但我仍然无法理解这种行为背后的逻辑。为了得到清晰的解释,我建议你自己管理最后一个值-这是我试图避免的,但是,似乎\u throttle
重新返回值的行为令人困惑,所以我可能会坚持处理该值myself@Maximus根据您所做的,您可能会考虑事件发射器模式。这允许消费代码在生成时只使用最新的值,或者在需要时存储以供以后使用。
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;
}