Существует два основных способа достижения «многопоточности» в Javascript. Первый способ - это кросс-браузерное решение, которое также работает в старых браузерах, но является более сложным в реализации.
Идея заключается в том, что вы даете пользовательскому интерфейсу время на обновление каждый раз через некоторое время. Поскольку в Javascript нет функции синхронного сна, единственный способ добиться этого - использовать setTimeout (или setInterval с немного более сложной логикой), чтобы задерживать выполнение каждого цикла ваших сложных вычислений. Это дало бы браузеру некоторое время для обновления пользовательского интерфейса между циклами, давая визуальный эффект нескольких вещей, происходящих одновременно. Нескольких мс должно быть более чем достаточно, чтобы пользовательский интерфейс отражал последние изменения.
Конечно, у него есть свои недостатки, и его может быть довольно сложно реализовать, если есть несколько действий, которые пользователь может захотеть сделать во время выполнения фоновых вычислений. Также он может значительно замедлить весь фоновый расчет, поскольку время от времени задерживается на несколько мс. В определенных случаях, однако, он делает свое дело и работает хорошо.
Второй вариант - использовать веб-работников, которые в основном являются сценариями Javascript, работающими независимо в фоновом режиме, как поток. Это намного проще в реализации, вам нужно только беспокоиться об обмене сообщениями между основным кодом и фоновыми рабочими, поэтому ваше приложение не будет затронуто так сильно. Вы можете прочитать об их использовании по ссылке, размещенной Mic https://developer.mozilla.org/en/Using_web_workers. Самым большим недостатком веб-работников является их поддержка браузерами, которую вы можете увидеть по адресу http://caniuse.com/#search=worker Нет никакого возможного обходного пути для IE <9 или мобильные браузеры, которые действительно имитируют эффект, поэтому с этими браузерами вы мало что можете сделать, но, опять же, преимущества современных браузеров могут перевесить плохую поддержку IE. Это, конечно, зависит от вашей заявки. </p>
Редактировать: Я не уверен, достаточно ли я объяснил первую концепцию, поэтому я решил добавить небольшой пример. Следующий код функционально эквивалентен:
for (var counter = 0; counter < 10; counter++) {
console.log(counter);
}
Но вместо записи 0-9 в быстрой последовательности он задерживается на 1 с перед выполнением следующей итерации цикла.
var counter = 0;
// A single iteration of your calculation function
// log the current value of counter as an example
// then wait before doing the next iteration
function printCounter() {
console.log(counter);
counter++;
if (counter < 10)
setTimeout(printCounter, 1000);
}
// Start the loop
printCounter();