Некоторое время назад я столкнулся с проблемой загрузки файлов с помощью 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
Большое спасибо за рецензию и комментарии к Дэвиду Лорбике.