Некоторое время назад я столкнулся с проблемой загрузки файлов с помощью Node.js.
Поскольку загрузка файлов в Node.js является асинхронной операцией, эта проблема показалась мне интересной, потому что с обещаниями javascript вы можете загружать файлы один за другим с помощью 'Promise.then ', либо начать их все асинхронно и дождаться результата с помощью' Promise.all '. Насколько мне известно, в javascript нет собственного механизма для разделения асинхронных задач по нескольким очередям, когда очереди выполняются асинхронно, но задачи внутри очереди выполняются последовательно.

Хотя эта проблема может быть чем-то, что другие разработчики решили с помощью разных библиотек, я хотел решить ее самостоятельно, так как казался более специфической и интересной проблемой, чтобы попытаться найти решение, особенно потому, что я хотел не только распространять асинхронные задачи по очередям, но также чтобы сделать их зависимыми от размеров загруженных файлов, чтобы они были сбалансированы.

Добавление кода для простой загрузки файла по URL-адресу несколько тривиально, и я не хотел бы засорять им этот пост, но я хотел бы уделить некоторое внимание коду того, как создать (с помощью javascript) абстрактный пул для взвешенных асинхронные задачи.

Pool интерфейс:

Реализация Pool:

Реализация очереди:

Потенциально Queue.add можно переписать с async/await и зацикливаться внутри вместо цепочки обещаний (остановить цикл проще, чем цепочку обещаний, но у нее также есть свои плюсы и минусы, выходящие за рамки этого поста).

И результат выполнения задач:

$ node tasks.js
Queue #1: task is started
Queue #2: task is started
Queue #3: task is started
Queue #4: task is started
Finishing task #4
Queue #4: task is finished
Queue #4: task is started
Finishing task #1
Queue #1: task is finished
Queue #1: task is started
Finishing task #6
Queue #1: task is finished
Queue #1: task is started
Finishing task #2
Queue #2: task is finished
Queue #2: task is started
Finishing task #3
Queue #3: task is finished
Queue #3: task is started
Finishing task #5
Queue #4: task is finished
Finishing task #9
Queue #3: task is finished
Finishing task #8
Queue #2: task is finished
Queue #2: task is started
Finishing task #10
Queue #2: task is finished
Finishing task #7
Queue #1: task is finished
All tasks are done

Большое спасибо за рецензию и комментарии к Дэвиду Лорбике.