Как я могу дать контроль назад (кратко) к браузеру во время интенсивной обработки JavaScript?

На этот вопрос нельзя ответить тем, что вы нам дали. Трудно найти исключение NullPointerException, если существует currentGroupModel, о котором мы ничего не знаем, и есть постоянные рыжие волосы. Например, почему вы храните что-то в ограниченном количестве, вы никогда не используете это! Почему вы передаете getTableRow rowIndex, который вы никогда не используете? Насколько я понимаю, ваш getTableRow возвращает последний TableRow в таблице, а не конкретный. Пожалуйста, подумайте об исправлении этих проблем, прежде чем в конечном итоге предоставить некоторый код, чтобы понять внутреннюю работу вашей currentGroupModel.

24
задан Jason Bunting 17 October 2008 в 03:18
поделиться

4 ответа

Вот решение:

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    '<option selected value="'+obj.data[0].value+'">'
    + obj.data[0].name
    + '</option>'
  );
  obj.data.splice(0, 1); // we only want remaining data
  var appendOptions = function() {
    var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs
    for(var i = 0; i < dataChunk.length; i++) {
      $("#mySelect").append(
        '<option value="' + dataChunk[i].value + '">'
        + dataChunk[i].name
        + '</option>'
      );
    }
    if(obj.data.length > 0) {
      setTimeout(appendOptions, 100); // change time to suit needs
    }
  };
  appendOptions(); // kicks it off
}

Не так элегантно, как @ решение Боргара , но вы поняли идею. По сути, я делаю то же самое, но все в одной функции, а не разбиваю ее на функцию более высокого порядка, как он. Мне нравится его решение, но если нет, возможно, это сработает для вас.


РЕДАКТИРОВАТЬ: Для тех, кто не видит его сразу, одно из основных различий между этим решением и @ Borgar's заключается в том, что это решение позволяет вам устанавливать размер «чанков». данных, которые обрабатываются между каждым тайм-аутом. @ Тайм-аут Боргара после обрабатывается каждый отдельный элемент массива. Если у меня будет время, я постараюсь создать функцию более высокого порядка, чтобы она была более элегантной. Никаких обещаний! ;)


РЕДАКТИРОВАТЬ: Итак, вот моя адаптация решения @ Borgar , которое позволяет более легко устанавливать размер «чанка» и настраивать значение тайм-аута:

function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) {
  var itemIndex = 0;
  (function() {
    var remainingDataLength = (data.length - itemIndex);
    var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength;
    if(itemIndex < data.length) {
      while(currentChunkSize--) {
        workerCallback(data[itemIndex++]);
      }
      setTimeout(arguments.callee, timeout);
    } else if(completionCallback) {
      completionCallback();
    }
  })();
}

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    '<option selected value="' + obj.data[0].value + '">'
    + obj.data[0].name
    + '</option>'
  );
  obj.data.splice(0,1); // we only want remaining data      
  incrementallyProcess(function(data) {
    $("#mySelect").append(
    '<option value="' + data.value + '">'
    + data.name
    + '</option>'
   );
  }, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required...
}

Надеюсь, что это помогает - я думаю, что это объединяет лучшее из обоих решений. Обратите внимание: вторая анонимная функция больше не использует значение индекса, а просто передает весь объект (со свойствами value и name); это делает его немного чище, поскольку индекс текущего объекта на самом деле не обычно , что полезно при итерации по вещам, IMO.

1113 Я уверен, что есть вещи, которые можно сделать, чтобы сделать это еще лучше, но это оставлено как упражнение для читателя. ;)

29
ответ дан 28 November 2019 в 23:08
поделиться

Это именно так происходит, который я отправлял об этом момент назад здесь . Вот синхронизированная функция цикла:

function processLoop( actionFunc, numTimes, doneFunc ) {
  var i = 0;
  var f = function () {
    if (i < numTimes) {
      actionFunc( i++ );  // closure on i
      setTimeout( f, 10 )
    } 
    else if (doneFunc) { 
      doneFunc();
    }
  };
  f();
}

Для Вашей ситуации это использовалось бы как это:

function appendToSelect () {

  $("#mySelect").children().remove() ;
  $("#mySelect").html(
      '<option selected value="' + obj.data[0].value + '">'
      + obj.data[0].name
      + '</option>'
  );
  var j = 1 ;

  processLoop(function (i){
    $("#mySelect").append(
        '<option value="' + obj.data[i].value + '">'
        + obj.data[i].name
        + '</option>'
    ); 
  }, obj.data.length);

}

Вы захотите удостовериться, что у Вас есть закрытие или некоторый другой доступ к obj переменной в итеративной функции.

Hope это помогает.

20
ответ дан 28 November 2019 в 23:08
поделиться

Если вам нужно что-то более простое, я написал плагин jQuery для облегчения написания асинхронных циклов: jQuery Async .

Используя плагин, ваш код может быть переписан как:

function appendToSelect() {
    $("#mySelect").children().remove() ;
    $("#mySelect").html(
        '<option selected value="' + obj.data[0].value + '">'
        + obj.data[0].name
        + '</option>'
    );

    /////////////////////////////
    var i = 1;
    $.whileAsync({
        test: function(){ i < obj.data.length; }
        loop: function()
        {
            $("#mySelect").append(
                '<option value="' + obj.data[i].value + '">'
                + obj.data[i].name
                + '</option>'
            ); 
            i++;
        }
    });
    /////////////////////////////
}

Должно помочь отзывчивость. Настройте параметры «bulk» и «delay» для большего контроля.

4
ответ дан 28 November 2019 в 23:08
поделиться

Необходимо было бы переписать функцию для кэширования списка элемента, затем цикл по списку с помощью какого-то счетчика.

Тогда, когда счетчик достигнет встречного % max_num_before_wait == 0, перезвоните тайм-ауту к самой функции.

Удостоверяются, что очистили кэш и счетчик в конце полного списка, или использовали вторичную функцию с дополнительным параметром количества.

-1
ответ дан 28 November 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: