在触发多项更改时,仅运行一次昂贵的代码

时间:2015-12-11 21:53:53

标签: javascript jquery

我有一些输入对象。

我有一个代码可以在更改时执行某些操作 -

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!
}

重新设计代码以防止在手动重置值时调用刷新的好方法是什么?承诺/ defferred会帮助吗?

3 个答案:

答案 0 :(得分: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])

答案 1 :(得分: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

答案 2 :(得分: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();