Проверка, запущен ли JavaScript setTimeout - PullRequest
3 голосов
/ 27 июля 2011

Я бы хотел иметь возможность отправлять через браузер кучу работ, которые должны быть выполнены в браузере таким образом, чтобы браузер оставался отзывчивым во всем.

Я пытаюсь использовать подходчтобы разделить работу на части, передавая каждый фрагмент функции, которая затем ставится в очередь с вызовом setTimeout(func, 0).

Мне нужно знать, когда вся работа выполнена, поэтому я сохраняю возвращенный идентификатор таймера вкарта (id -> true | false).Это отображение устанавливается в false в следующем блоке кода после того, как у меня есть идентификатор таймера, а функция в очереди устанавливает отображение в true, когда оно завершается ... за исключением того, что функция в очереди не знает свой идентификатор таймера.

Может быть, есть лучший / более простой способ ... или какой-нибудь совет о том, как я могу манипулировать своей картой так, как мне нужно?

Ответы [ 3 ]

6 голосов
/ 27 июля 2011

Я бы поставил в очередь работу в массиве, использовал бы один тайм-аут для обработки очереди и вызвал бы обратный вызов, когда очередь пуста.Что-то вроде:

var work = [...];

var run = function(work, callback) {
    setTimeout(function() {
        if(work.length > 0) {
            process(work.shift());
            setTimeout(arguments.callee, 25);
        }
        else {
            callback();
        }
    }, 25);
};

run(work, function() {
    alert('Work is done!');
});

Поскольку JavaScript в браузерах является однопоточным, нет никакого реального преимущества для запуска нескольких тайм-аутов (по крайней мере, я думаю, что вы это делаете).Это может даже замедлить работу браузера.

1 голос
/ 23 сентября 2011

Я хотел бы добавить, что, хотя javascript является однопоточным, вы все равно можете выполнять несколько вызовов ajax одновременно.Недавно у меня был сайт, на котором требовалось выполнять сотни вызовов ajax, и браузер просто не мог с этим справиться.Я создал очередь, которая использовала setTimeOut для запуска 5 вызовов одновременно.Когда один из возвращенных вызовов ajax вызвал обратный вызов (который обрабатывается одним потоком), а затем сделал следующий вызов в стеке.

Представьте, что вы менеджер, который может разговаривать только с одним человеком навремя вы даете 5 назначений сотрудникам, затем ждете их ответов, которые могут прийти в любом порядке.Как только первый сотрудник возвращается и предоставляет вам информацию, вы даете ему новое назначение и ждете возвращения следующего сотрудника (или, возможно, даже того же сотрудника).Так что, хотя вы «однопоточны», 5 вещей происходят одновременно.

0 голосов
/ 13 мая 2019

В стандарте HTML есть пример, как лучше всего с ним справиться:

Для запуска задач в несколько миллисекунд без задержки, в то же время возвращаясь к браузеру, чтобы избежать голода интерфейс (и чтобы браузер не убивал скрипт для CPU), просто поставьте в очередь следующий таймер перед выполнением работы:

function doExpensiveWork() {
  var done = false;
  // ...
  // this part of the function takes up to five milliseconds
  // set done to true if we're done
  // ...
  return done;
}

function rescheduleWork() {
  var handle = setTimeout(rescheduleWork, 0); // preschedule next iteration
  if (doExpensiveWork())
    clearTimeout(handle); // clear the timeout if we don't need it
}

function scheduleWork() {
  setTimeout(rescheduleWork, 0);
}

scheduleWork(); // queues a task to do lots of work

Момент завершения работы довольно ясен, когда вызывается clearTimeout.

...