Вы не хотите, чтобы ваш процессор с интенсивным использованием процессора выполнял асинхронно, вы хотите, чтобы он выполнял параллельно . Вам нужно вывести обработку из потока, который обслуживает HTTP-запросы. Это единственный способ решить эту проблему. С NodeJS ответом является кластерный модуль для порождения дочерних процессов для выполнения тяжелой работы. (У узла AFAIK нет понятия потоков / разделяемой памяти; это процессы или ничего). У вас есть два варианта структуры вашего приложения. Вы можете получить решение 80/20, создав 8 HTTP-серверов и синхронно обрабатывая ресурсоемкие задачи на дочерних процессах. Делать это довольно просто. Вы можете потратить час, чтобы прочитать об этом по этой ссылке. На самом деле, если вы просто скопируете пример кода в верхней части этой ссылки, вы получите 95% пути.
Другой способ структурировать это - настроить очередь заданий и отправить по ней большие вычислительные задачи. Обратите внимание, что с IPC связано много накладных расходов для очереди заданий, так что это полезно, только когда задачи заметно превышают накладные расходы.
Я удивлен, что ни один из этих других ответов даже не упоминает кластер.
Справочная информация:
Асинхронный код - это код, который приостанавливается до тех пор, пока что-то не произойдет где-то еще , после чего код активизируется и продолжит выполнение. Один очень распространенный случай, когда что-то медленное должно произойти где-то еще, - это ввод-вывод.
Асинхронный код бесполезен, если за выполнение этой работы отвечает ваш процессор . Именно так обстоит дело с «интенсивными вычислениями».
Теперь может показаться, что асинхронный код - это ниша, но на самом деле он очень распространен. Просто это бывает бесполезно для сложных задач.
Ожидание ввода-вывода - это шаблон, который всегда происходит, например, на веб-серверах. Каждый клиент, который подключается к вашему серверу, получает сокет. Большую часть времени розетки пусты. Вы не хотите ничего делать, пока сокет не получит некоторые данные, после чего вы захотите обработать запрос. Внутренний HTTP-сервер, такой как Node, использует библиотеку событий (libev) для отслеживания тысяч открытых сокетов. ОС уведомляет libev, а затем libev уведомляет NodeJS, когда один из сокетов получает данные, а затем NodeJS помещает событие в очередь событий, и ваш http-код активируется в этот момент и обрабатывает события одно за другим. События не помещаются в очередь до тех пор, пока в сокете не будет данных, поэтому события никогда не ждут данных - они уже там.
Однопоточные веб-серверы, основанные на событиях, имеют смысл в качестве парадигмы, когда узкое место ожидает куча в основном пустых соединений сокетов, и вам не нужен целый поток или процесс для каждого неактивного соединения, и вы не хотите опросите свои 250k сокетов, чтобы найти следующий, на котором есть данные.