这不是一个特别的技术问题,但我很好奇这个问题的最佳方法是什么?虽然我在Knockout中遇到了这个问题,但我确信用例在其他地方也会有效。
假设我已经订阅了2个变量simpleObserve1
,simpleObserve2
,以便每当它们的值发生变化时,就会调用函数resetAllValues()
。
var simpleObserve1 = ko.observable(0), // initial values
simpleObserve2 = ko.observable(0); // initial values
var resetAllValues = function resetAllValues() {
/* this function takes all observable values and resets them */
{...}
}
simpleObserve1.subscribe(function(){
resetAllValues();
});
simpleObserve2.subscribe(function(){
resetAllValues();
});
simpleObserve1(5); // value changed anywhere in code
simpleObserve2(10); // value changed anywhere in code
这里有2个问题。
simpleObserve1
和simpleObserve2
。这反过来又一次调用resetAllValues()
。如何防止这种情况进入无限循环?resetAllValues()
一次会怎么样?我尝试使用knockout's dispose()方法来帮助我,但我想知道是否有更好的方法来做到这一点。
答案 0 :(得分:1)
Deferred Updates可能会帮助你。通过使用observables'计算中的值,knockout创建订阅。通过扩展这个计算,快速成功的变化被组合在某种微任务中。
它们阻止了循环行为,但仍然不清楚触发了多少更新。 I.e。:设置为5
和10
时会导致 1 或 2 计算更新。所以我不完全确定这是否能回答你的问题。
var i = 0,
simpleObserve1 = ko.observable(0), // initial values
simpleObserve2 = ko.observable(0); // initial values
ko.computed(function resetAllValues() {
console.log("Set " + ++i + ", before:");
console.log("1: ", simpleObserve1());
console.log("2: ", simpleObserve2());
simpleObserve1(0);
simpleObserve2(0);
console.log("Set " + i + ", after:");
console.log("1: ", simpleObserve1());
console.log("2: ", simpleObserve2());
}).extend({
deferred: true
});
simpleObserve1(5); // value changed anywhere in code
simpleObserve2(10); // value changed anywhere in code

.as-console-wrapper { min-height: 100%; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;
答案 1 :(得分:0)
我创建了一个更高阶函数acceptXParams
,它将检查参数的数量是否等于fn.length
或任意数字。如果不是,则不会调用原始函数:
function acceptXParams(fn, numOfParams) {
var numOfParams = numOfParams === undefined ? fn.length : numOfParams;
return function() {
if(arguments.length !== numOfParams) {
return;
}
return fn.apply(fn, arguments);
}
}
/** example **/
function sum(a, b, c) {
return a + b + c;
}
var sum3 = acceptXParams(sum);
console.log(sum3(1, 2, 3));
console.log(sum3(1, 2));
console.log(sum3(1, 2, 3, 4));
更整洁的ES6版本acceptXParams
:
const acceptXParams = (fn, numOfParams = fn.length) =>
(...args) =>
args.length === numOfParams ? fn(...args) : undefined;