Зачем нам трубка или сочинение?

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

  1. Нужно следить за this. И значение должно быть сохранено в операторе this, чтобы функции, связанные позже, получили доступ к этому значению.
  2. Синтаксис не совсем интуитивно понятный. Если бы функций было много, это выглядело бы примерно так - ›functionA().functionB().functionC().functionD().......functionZ().

Чтобы уменьшить влияние этих двух предостережений, можно использовать реализацию функций pipe() и compose().

трубка()

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

  1. Унарная реализация:
pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

pipe(
    add,
    multiply,
    double,
    divide
)(5)

Давайте разберем приведенную выше реализацию:

  • Здесь используется метод reduce, представленный в реализации массива javascript. Базовый синтаксис f! Или этой реализации выглядит следующим образом: [1,2,3].reduce((av, val) => av + val, x). Здесь функция начинается с начальной переменной x, затем проходит по массиву и вызывает анонимную функцию с двумя значениями: накопленное значение и текущее значение. Реализация функции зависит от пользователя.
  • Оператор распространения используется для преобразования входного списка функций в массив. Это помогает в реализации функции уменьшения.
  • Когда вызывается функция reduce, следующая функция в списке становится текущим значением, а значение, возвращенное предыдущей функцией, становится накопленным значением.
  • Массив повторяется до конца.

2. Реализация нескольких операторов:

pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));

pipe(
    add,
    multiply
)(10, 10);
  • В этом случае, поскольку начальное значение не предоставляется, первый аргумент (функция add) рассматривается как накопленное значение для первой итерации. Следовательно, текущее значение естественным образом становится функцией умножения. Мы передаем список аргументов ...args накопленному значению (функция сложения), а выходные данные функции передаются функции умножения.
  • Если вторая функция должна получить несколько аргументов, убедитесь, что первая функция возвращает список аргументов.

составить ()

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

compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);

compose(
    divide,
    double,
    multiply,
    add
)(5)
  • Метод reduceRight также предоставляется как одна из стандартных реализаций итерации массива. Это анализирует значения справа налево.
  • Список функций принимается в виде массива, и обработка начинается с нижней функции add.
  • Показанная выше реализация работает так же, как реализация pipe().

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