2017-02-15 7 views
0

Я пытаюсь реализовать дросселируемое обновление пользовательского интерфейса с нокаутом, то есть разделить цикл на куски с некоторым временным интервалом между ними, чтобы дать браузеру некоторую комнату для передышки, чтобы быть более отзывчивой на больших массивы.Процесс нокаута foreach в кусках с таймаутом между

Вот что я имею прямо сейчас. Моя проблема в том, что она, кажется, застревает в бесконечном цикле. Возможно, из-за отслеживания зависимостей. Что мне не хватает?

$(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/

+0

На данный момент ваши «предметы» не рассчитаны, потому что у него нет зависимостей. Он не использует внешние наблюдаемые данные, поэтому он никогда не будет активирован для обновления, и это победит цель использования вычисленного. Единственным наблюдаемым, которое он использует, является тот, который он создает в своем собственном теле, и его отбрасывают, как только функция заканчивается, потому что вы возвращаете только развернутый плоский массив. Поэтому я думаю, вам, возможно, потребуется переосмыслить всю концепцию. –

+0

Вы пробовали https://github.com/brianmhunt/knockout-fast-foreach? –

+0

@JasonSpake В моем фактическом коде есть зависимости. Я должен был сделать это более ясным в вопросе – Johan

ответ

0

Я не понимаю, почему ваш 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/

+0

Спасибо за ваше предложение. Я думаю, что мне нужно будет использовать вычисление, потому что в моем фактическом коде у меня есть некоторые другие зависимости, которые влияют на список. Если я просто использую IIFE, я потеряю отслеживание зависимостей, правильно? – Johan

+0

Да, если вы хотите отслеживание зависимостей, вам потребуется вычислить. Проблема в том, что ваш 'computed' переоценивает каждый раз, когда вы« нажимаете », снова включаете' throttledPush' * *. Это побочный эффект, который не может быть у вас в 'pureComputed'. Т.е.: 'наблюдаемый()' используется в вычисляемом -> он повторно оценивает -> он * изменяет * 'наблюдаемый()' * снова * -> он переоценивает -> и т. Д. – user3297291

+0

Хорошо .. перечитывая, что последний мой комментарий: не совсем понятно, что я имею в виду. Проверьте этот дополнительный «журнал», чтобы увидеть, что ваши вычисленные повторные оценки, создание новых массивов и тайм-аутов. https://jsfiddle.net/ve5kfrd2/ Если вы покажете немного больше своего кода (включая «зависимости»), я мог бы помочь найти альтернативный подход. – user3297291

0

решаемые подписавшись на вычисленное и заполнение наблюдаемого массива в обратном вызове подписки.