2015-12-11 5 views
1

У меня есть несколько объектов ввода.Запуск дорогого кода только один раз, при запуске нескольких изменений

У меня есть код, который делает что-то, когда они изменяются -

for (var i=0; i<100; ++i) 
    my_inputs[i].on('change', function() { 
    showValue($(this).val()); // Display the value it changed to 
    someExpensiveOperation(); // A common refresh for any change 
    }); 

Я хочу, чтобы сбросить все из них 0.

for (var i=0; i<100; ++i) { 
    my_inputs[i].val(0); 
    my_inputs[i].change(); // Calls someExpensiveOperation 100 times! 
} 

Что хороший способ перестроить свой код, чтобы предотвратить обновление происходит при ручном сбросе значений? Будет ли обещать/отменять помощь здесь?

+1

"Будут ли обещание/defferred помощи здесь?" Нет. Вы можете определить функцию _general_ refresh и вызвать ее один раз после цикла. – undefined

+0

Если вы выполняете 'someExpensiveOperation' после * каждого * обновления для своего массива, и это уже вызывает проблемы, возможно, вы должны делать« someExpensiveOperation »немного разумнее. – jered

ответ

2

Вы можете дребезг звонков someExpensiveOperation():

var someExpensiveOperationDebouncing = 0; 

function debouncedSomeExpensiveOperation() { 
    if (someExpensiveOperationDebouncing) { 
     return; 
    } 

    // wait at least 1/4 second before calling someExpensiveOperation again 
    ++someExpensiveOperationDebouncing; 
    setTimeout(function() { 
     --someExpensiveOperationDebouncing; 
    }, 250); 

    someExpensiveOperation.apply(this, arguments); 
} 

также посмотреть на lodash-х _.debounce(func, [wait], [options]).

+0

Это ставит ответственность на 'debouncedSomeExpensiveOperation', но если требование - вызвать' someExpensiveOperation' только после завершения подготовки (цикл ...), это опасно – Amit

+0

Это действительно работает для меня :) Это красиво инкапсулирует логики в одном месте. – KalEl

1

Вероятно, лучше иметь флаг испытания внутри someExpensiveOperation:

function someExpensiveOperation() { 
    if(skipExpensive) { 
    return; 
    } 
    // real work below... 
} 

skipExpensive = true; 
for (var i=0; i<100; ++i) { 
    my_inputs[i].val(0); 
    my_inputs[i].change(); 
} 
skipExpensive = false; 
someExpensiveOperation(); 
+0

Итак, создайте флаг, чтобы отключить его, если это необходимо! Довольно умный - спасибо. – KalEl

2

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

function specialOperation(input) { 
    showValue($(this).val()); // Display the value it changed to 
} 
for (var i = 0; i < 100; ++i) 
    my_inputs[i].on('change', function() { 
     specialOperation(my_inputs[i]); 
     someExpensiveOperation(); // A common refresh for any change 
    }); 

Код сброс будет стать:

for (var i=0; i < 100; ++i) { 
    my_inputs[i].val(0); 
    specialOperation(my_inputs[i]); 
} 
someExpensiveOperation(); // A common refresh for any change 
+0

Поэтому вместо вызова change() я вызываю внутренние механизмы отдельно. Хорошее решение :) Спасибо! – KalEl

Смежные вопросы