Рубрики
Без рубрики

Создание одновременного очереди обещания с JavaScript

Как создать очередь обещания в JavaScript с использованием как параллельных и последовательных методов.

Автор оригинала: Edafe Emunotor.

Потратили часы, ищущая сырную цитату, чтобы начать с🧐, не могла найти тот, который пошел с обещаниями😫.

Ну, давайте прыгать в.

Обещания !!! 🚦 Если вы работаете с JavaScript, вы встретите их каждый день. Если вы работаете на большом продукте, вы бы столкнулись с проблемой необходимости служить нескольким запросам сторонним API. Как разработчик Backeng, работающий в Fintech Space, одна рецидивирующая проблема, которую я продолжаю столкнуться, служит и перерабатывает оптовые запросы клиентов. Большинство людей хотят иметь возможность загрузить файл CSV Account Account (дебетовые/кредитные) запросов и выполнял их оперативно.

Хотя существует более оптимальные методы решения такого рода проблем, JavaScript безблокирующая асинхронный рисунок обеспечивает довольно наивный подход, который помогает вам обрабатывать несколько задач ввода/вывода, которые не подавляют контуру события. Давайте сделаем быстрое прогон на основах обещаний.

Что обещание?

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

Решение обещаний

const transactionStatus = (seconds) => new Promise((resolve, reject) => {
  setTimeout(() => {
    	resolve('Your transaction is successful');
    }, seconds * 500); //second argument is in milliseconds
})

Вызывая наше обещание

transactionStatus(2)
  .then((result) => console.log(result));
result: Your transaction is successful

PS: Есть нефте-маленький трюк, который мы можем сделать выше. Наше .then () Блок принимает в функцию, которая принимает аргумент и входит в систему. С console.log делает то же самое, я могу заменить всю функцию в .then () Метод с console.log

transactionStatus(2)
  .then(console.log);

Результат будет таким же

result: Your transaction is successful

Обещания цепилины. Вызывание нашего обещания выше может включать несколько .then () методы.

transactionStatus(2)
  .then(console.log)
  .then(() => 200)
  .then((status) => console.log('Transaction fetched', status));
result: Your transaction is successful
result: Transaction fetched 200

Отклонение обещаний

Если что-то пойдет не так внутри обещания, мы можем цепить .catch () Способ обрабатывать его (ошибки, которые происходят в наших кодах). Мы также можем пройти ошибку к .catch () Метод, если мы вызываем Отклонить () метод.

const transactionStatus = (seconds) => new Promise((resolve, reject) => {
    if(seconds > 25){
        reject(new Error('Request timed out'));
    }
    setTimeout(() => {
        resolve('Your transaction is successful');
    }, seconds * 1000); 
 });
 
transactionStatus(26)
    .then(console.log)
    .then((status) => console.log('Transaction fetched', status))
    .catch((error) => {
         console.log(error.message);
    });

result: Request timed out

Способность цепи несколько .then () Предложите нам возможность выполнить обещания последовательно Отказ

const fetchTransactionStatus = () => Promise.resolve()
  .then(() => console.log('Begin request')
  .then(() => transactionStatus(5))
  .then(() => console.log)
  .then(() => console.log('End Request'))

Каждый из .then () выполняет последовательно и производить следующий результат.

result: Begin request
result: Your transaction is successful
result: End Request

Параллельное исполнение

Выполнение нескольких задач одновременно упоминается как параллельное исполнение. JavaScript предоставляет Обещание. Все () Метод, который позволяет нам реализовать параллельное выполнение.

Promise.all([
  transactionStatus(15),
    transactionStatus(5),
    transactionStatus(20)
]).then(() => console.log('All transaction requests resolved'))

result: All transaction requests resolved //prints after 20seconds

Код выше будет ждать всех трех обещаний для разрешения до регистрации сообщения в .then () Блок. Это означает, что это займет 20 секунд для полной решающей.

Если мы хотим наше .then () Блок для регистрации нашего сообщения после первого обещания с меньшим количеством времени выполняется, оберните обещания в Promess.race () Отказ

Promise.race([
  transactionStatus(15),
    transactionStatus(5),
    transactionStatus(20)
]).then(() => console.log('transaction requests resolved'))
result: transaction requests resolved (logs after 5seconds)

Очередь одновременного обещания

Обработка нескольких асинхронных задач – это то, что у Nodejs есть механизм для обработки хорошо. Хотя есть лучшие способы обработки больших некроноронных задач, таких как реализация правильной системы очередей с помощью rabbitmq, Amazon SQS, пользовательских очередь SQL ETC, наивный подход может быть реализован с очередной очередью.

Я говорил о выполнении обещаний как последовательно, так и параллельно. Запуск нескольких асинхронных задач последовательно потребуется дольше, и если вы запустите их параллельно, она будет потреблять больше ресурсов. Тем не менее, мы можем объединить оба метода для создания очереди обещания, которые будут быстрее и потреблять меньшего количества ресурсов.

Шаг 1 : Создайте массив обещаний.

const tasks = [
  transactionStatus(5),
  transactionStatus(15),
  transactionStatus(2),
  transactionStatus(4),
  transactionStatus(6),
  transactionStatus(9),
  transactionStatus(11),
  transactionStatus(12),
  transactionStatus(10)
];

Шаг 2 : Создайте функцию конструктора, которая принимает два параметра, A Задачи Массив и A commentcount Целое число для установки максимального количества обещаний, которые должны быть в рабочем состоянии. Мы также создаем массив, который проводит обещания, которые в настоящее время работают, и другой массив, который содержит обещания, которые завершены.

Создание нашей функции конструктора очереди.

function PromiseQueue(tasks = [], concurrentCount = 1) {
 this.total = tasks.length;
 this.todo = tasks;
 this.running = [];
 this.complete = [];
 this.count = concurrentCount;
}

Шаг 3 : Создайте метод, который отслеживает состояние очереди задач. Это определит, должен ли бегун продолжать выполнение или выйти. Это также гарантирует, что у нас не будет больше указанного одновременного подсчета в Runner Cass Runner.

PromiseQueue.prototype.runNext = function(){
  return ((this.running.length < this.count) && this.todo.length);
}

Шаг 4 : Создайте заданный бегун. Мы будем перемещать задания из списка TodDo в списку, после выполнения, мы перемещаем их в завершенный список.

PromiseQueue.prototype.run = function () {
  while (this.runNext()) {
    const promise = this.todo.shift();
    promise.then(() => {
      this.complete.push(this.running.shift());
      this.run();
    });
    this.running.push(promise);
  }

}

Шаг 5 : Идите вперед и создайте нашу функцию очереди обещания. Мы можем вызвать метод .run () для запуска нашей очереди задач.

const taskQueue = new PromiseQueue(tasks, 3); //tasks = an array of aysnc functions, 3 = number of tasks to run in parallel
taskQueue.run();

Заключение

Одной из причин, по которой этот наивный подход не масштабируемый, это становится очень сложным для отслеживания сбоев и инициированных повторных попыток. Как насчет того, чтобы запросы растут до 20 000 задач, это становится чрезвычайно неуправляемым. Именно поэтому более надежная система массовой очереди, которая облегчает реализацию управления очередью, является предпочтительным подходом. Тем не менее, обучение того, как создать параллельное Очередь обещания дает нам лучшее понимание того, как JavaScript обещает работу.