При разработке больших скриптов на JavaScript часто возникает ситуация, когда множество задач пытается выполниться одновременно. Это может привести к зависаниям интерфейса или ошибкам. Решением является использование очередей (queues). Очередь — это структура данных, которая организует задачи по принципу «первым пришёл — первым вышел» (FIFO). В этой статье мы разберём, как реализовать и использовать очереди для плавной работы вашего приложения.
JavaScript является однопоточным языком, но он умеет работать с асинхронными операциями, такими как запросы к серверу или таймеры. Если таких операций становится слишком много, их нужно упорядочить. Очередь помогает:
Давайте создадим базовый класс TaskQueue. Он будет хранить задачи в массиве и выполнять их последовательно.
class TaskQueue {
constructor() {
this.tasks = [];
this.isRunning = false;
}
enqueue(task) {
this.tasks.push(task);
if (!this.isRunning) {
this.runNext();
}
}
runNext() {
if (this.tasks.length === 0) {
this.isRunning = false;
return;
}
this.isRunning = true;
const currentTask = this.tasks.shift();
// Предполагаем, что задача возвращает промис
Promise.resolve(currentTask())
.finally(() => {
this.runNext();
});
}
}Представьте, что вам нужно последовательно отправить несколько запросов на сервер без перегрузки сети. Вот как это сделать с помощью нашей очереди:
const requestQueue = new TaskQueue();function fetchUserData(id) { return () => fetch(`/api/user/${id}`); }requestQueue.enqueue(fetchUserData(1));
requestQueue.enqueue(fetchUserData(2));Теперь запросы будут отправляться по одному, даже если вы добавили их все одновременно. Это особенно полезно при работе с ограниченными ресурсами или API, которые имеют лимиты на количество обращений.
В более сложных сценариях может потребоваться выполнять не одну, а несколько задач параллельно, но не больше заданного лимита. Для этого нужно модифицировать класс, добавив счетчик активных задач и проверку на доступные «слоты». Такой подход называется «пулом потоков» (Thread Pool) и широко используется для управления одновременными операциями.