我正在尝试通过淘汰来实现一个受限制的 UI 更新,即在块中拆分一个循环,中间有一些超时,给浏览器一些喘息的空间,以便在大型数组上做出更快的响应。
这是我现在所拥有的。我的问题是它似乎陷入了无限循环。可能是由于依赖关系跟踪。我错过了什么?
$(function(){
var ViewModel = function(){
this.items = ko.pureComputed(function(){
var observable = ko.observableArray(),
items = [];
for(var i = 0; i < 100; i++) {
items.push({ text: Math.random().toString(36).substring(7) });
}
throttledPush(observable, items);
return observable();
}, this);
};
ko.applyBindings(new ViewModel());
});
function throttledPush(obsArray, array, items, timeout) {
items = items || 5;
timeout = timeout || 500;
var cancel = false;
var i = 0;
function addItems() {
if (cancel) return;
obsArray.valueWillMutate();
for (var j = 0; j < items && i < array.length; ++j && ++i) {
console.log('push');
obsArray().push(array[i]);
}
obsArray.valueHasMutated();
if (i < array.length) setTimeout(addItems, timeout);
}
addItems();
return {
cancel: function() {
cancel = true;
},
};
}
https://jsfiddle.net/h6d4dfsc/
我不明白为什么你的items
属性需要是一个ko.pureComputed
。您可以将其替换为返回普通observable
的自执行函数,一切似乎都正常工作:
this.items = (function(){
var observable = ko.observableArray(),
items = [];
for(var i = 0; i < 100; i++) {
items.push({ text: Math.random().toString(36).substring(7) });
}
throttledPush(observable, items);
return observable;
}());
如果您希望这是可重用的,我建议使用扩展器。
我还没有完全阅读实际的油门代码...我突然意识到计算可能是实际问题。如果您仍然遇到问题,请告诉我:我也可以花更多时间阅读代码的其他部分:)
在这里更新小提琴:https://jsfiddle.net/9rqxo2p5/
通过订阅计算并在订阅回调中填充可观察数组来解决。