12 Home
Svinokot edited this page 6 months ago

Task Queue JS

Хороший способ создания ассинхронных сценариев при помощи теории множеств.

Содержание

  1. Task Queue Api
  2. Основные сценарии
  3. Примеры

Введение

task-queue-js представляет собой шаблон разработки и утилиту для организации модульных ассинхронных сценариев. Относится к прослойке, между API приложения и HTTP клиентом. К основным особенностям можно отнести:

  1. Полиморфизм
  2. Автономность

Полиморфизм

Каждый сценарий может быть самостоятельным множеством (надмножеством), так и подмножеством другого сценария, а также являться собственным множеством, т. е. содержать само себя и, таким образом, организовывать рекурсию.

Проще говоря, мы можем:

  1. создавать атомарные сценарии, применимые сразу к нескольким похожим ситуациям;
  2. комбинировать простые сценарии, создавая более сложные;
  3. лучше структурировать код.

Например, напишем атомарные сценарии и попробуем применить из в различных ситуациях.

/* Несколько атомарных сценариев */
const getOrange = (data) => ({...data, orange: data.orange + 1});
const getApple = (data) => ({...data, apple: data.apple + 1});

/* 
 * Этот базовый сценарий может положить в корзину апельсин и яблоко,
 * но корзина на данный момент ещё не определена.
 */
const basketScenario = join(getOrange, getApple);

Теперь, вызывая basketScenario(data) с различными начальными (data) данными мы можем получать релевантный результат.

basketScenario({orange: 0, apple: 0}).then(console.log);
> {orange: 1, apple: 1}

Практически, если в качестве начальных данных отправить id, то используя один и тот же сценарий, можно запрашивать разные страницы и класть туда фрукты.

const getPage = ({ id }) => fetch( ... );
const pageScenario = join(getPage, basketScenario);

pageScenario({ id: 1 }).then(console.log);

Такой подход хорошо подходит для работы с микросервисной архитектурой, где процедура запроса совершается в несколько этапов. В task-queue-js это можно свободно организовать. При этом код для одного запроса не будет смешиваться с кодом других запросов.

const getUser = ({ id }) => fetch( ... ).then(user => { guid: user.guid });
const getAvatar = ({ guid }) => fetch( ... ).then(avatar => { avatar });

const profileScenario = join(getUser, getAvatar);
...
profileScenario({ id: 1 }).then(console.log);
> { id: 1, guid: '...', avatar: '...' }

Этот же сценарий можно использовать в других, более сложных сценариях...

const getItems = ({ id }) => fetch( ... ).then(items => { items });
const getLog = ({ id }) => fetch( ... ).then(log => { log });
const calc = ({ items, log }) => ({ count: items.length + log.length });

const pageScenario = join(
  all(
    getItems,
    getMetadata,
    put('profile', profileScenario) // <-- Вот он!
  ),
  calc
);

pageScenario({ id: 1, profile: { id: 2 } }).then(console.log);
> {
    id: 1,
    items: [],
    log: [],
    count: 42,
    profile: { id: 2, guid: '', avatar: '' }
  }

Автономность

task-queue-js не требует других фреймворков для работы. Также, он может быть использован совместно с другой технологией, дополняя её.