Как выполнить многопоточность в Node.js

Прошло уже пять лет с тех пор, как Node.js представил собственную библиотеку worker_threads, предназначенную для создания воркеров, по сути функционирующих как потоки.
Когда он был выпущен, я был полон энтузиазма и стремился создать что-то интересное в этом плане.
Обсуждая рабочие потоки, я заметил, что не каждому удается построить правильную систему, использующую worker_threads. Следовательно, я начал поиск абстракций, которые могли бы упростить и расширить возможности для более интригующих решений.
Я наткнулся на несколько интригующих абстракций, но в конечном итоге решил разработать свою собственную — легкую и понятную.
веселые нити
Идея проста: вы можете выполнить свою функцию в выделенном потоке, используя Promises.
import executeInThread from 'funthreads';
async function calculate() {
const values = await Promise.all([
executeInThread(() => 2 ** 10),
executeInThread(() => 3 ** 10)
]);
console.log(values);
}
calculate();
Вы можете переместить операции с интенсивным использованием ЦП в отдельные потоки и легко получать результаты с помощью Promises.
Просто попробуйте себя и увидите.
$ npm i funthreads
https://github.com/nairihar/funthreads
Я не потратил много времени на эту библиотеку, и хотя я не использовал ее в реальном проекте, я остался в восторге и со временем внес небольшие улучшения.
После публикации этой библиотеки я заметил другие расширенные реализации той же идеи.
пул потоков-узлов-работников
Как описывают авторы: Простой пул рабочих потоков с использованием модуля worker_threads Node. Совместим с ES6+ Promise, Async/Await и TypeScript🚀.

Но это еще не все, есть еще одна библиотека, выпущенная еще до worker_threads.

Раньше они использовали различные стратегии и подходы для поддержки многопоточности. Однако после worker_threads их реализация значительно улучшилась.
Вот краткий пример, иллюстрирующий, как работает библиотека.
// main.js
import { spawn, Thread, Worker } from "threads"
const auth = await spawn(new Worker("./workers/auth"))
const hashed = await auth.hashPassword("Super secret password", "1234")
console.log("Hashed password:", hashed)
await Thread.terminate(auth)
// worker.js
import sha256 from "js-sha256"
import { expose } from "threads/worker"
expose({
hashPassword(password, salt) {
return sha256(password + salt)
}
})
Кажется, это самая большая библиотека, предоставляющая кучу инструментов для работы с многопоточностью в Node.js.
P.S. Обе библиотеки предлагают метод создания пула потоков и использования его для конкретных случаев использования.
К сожалению, ни один из них я не использовал в производстве, так как не было необходимости. Однако я уверен, что многие проекты могут извлечь из них пользу в реальных сценариях.
Интересно наблюдать, как они работают, и понимать механику абстракции.
Библиотека funthreads довольно проста и состоит всего из нескольких файлов с небольшими функциями. Вы можете начать с него, и я уверен, что вы легко поймете эту концепцию, понимая, насколько проста предоставленная абстракция.
Подведение итогов
По сравнению с другими языками программирования в JavaScript все совсем по-другому. Все происходит по-своему и имеет свое объяснение.
В JavaScript есть классы, а Node.js поддерживает многопоточность. Хотя это может показаться ошеломляющим по сравнению с другими языками, важно учитывать его уникальность.
Благодарим вас за то, что нашли время прочитать эту подробную статью.
Не стесняйтесь задавать любые вопросы или писать мне в Твиттере @nairihar
Также следите за моей рассылкой JavaScript в Telegram: @javascript
Надеюсь, вы нашли это информативным и почерпнули из него ценную информацию.