Javascript по своей природе асинхронный. Он использует события (обратные вызовы, тайм-ауты) для управления выполнением многих быстрых вызовов функций. Nodejs не имеет пользовательского интерфейса для блокировки, но эти быстрые функции могут быть заблокированы медленной функцией. Эта асинхронная природа Javascript применима как к nodejs, так и к коду браузера.
Я полагаю, что ваш вопрос о том, как справляться с операциями, занимающими много времени.
Один из подходов заключается в разбейте эти операции на множество частей - быстрых вызовов функций - и пусть каждая из них использует setTimeout()
для запуска следующей. Трудно предположить, как это сделать, не понимая ваших долгосрочных функций. Вот вопрос и некоторые ответы на топи c. Как разбить долгосрочную функцию в javascript, но сохранить производительность
Обобщая ответ, вы используете этот вид кода.
function (data, callbackWhenDone) {
let n = 0
const max = data.length;
const batchSize = 100;
try {
function doBatch () {
let i
for (var i = 0; i < batch && n < max; ++i, ++n) {
doComputation(data[n])
}
if (n < max) setTimeout(doBatch, 0)
else callbackWhenDone(null, data)
}
} catch (error) {
callbackWhenDone(error)
}
doBatch()
}
setTimeout(fn,0)
в конце партии запускает следующую партию, поставив в очередь таймаут в Javascript основной л oop. Другие предметы в этой очереди получают шанс на запуск. Каждый пакет знает, с чего начать, потому что функция doBatch()
обновляет n
при запуске. Когда весь лот заканчивается, он вызывает обратный вызов, который вы передали. В обратном вызове используется типичный шаблон nodejs, где первый параметр, если не ноль, является ошибкой.
Другой подход заключается в использовании Рабочие темы . Вы можете поместить Javascript код вашего вычисления в отдельный контекст Javascript и запустить его. Вам понадобится умение передавать данные назад и вперед из основного процесса nodejs в поток. Убедитесь, что у вас есть надежная настройка отладчика, прежде чем попробовать это; это может сбивать с толку.