Композиция функций в программировании

Материал из Циклопедии
Перейти к навигации Перейти к поиску

Композиция функций — это преобразование последовательности функций (значений функционального типа: функций, анонимных функций, лямбда-выражений, методов) в одну функцию (значение функционального типа). При композиции результат предыдущей функции становится аргументом следующей, которая, в свою очередь, возвращает результат, который передается в качестве а аргумента третьей и так далее. Пример на двух функциях:<syntaxhighlight lang="javascript"> // композиция двух функций

const compose = (f1, f2) => x => f2(f1(x));

// пример использования

const upperCapital = s => s.replace(

 /\w+/g, word => word.charAt(0).toUpperCase() + word.substr(1)

);

const lower = s => typeof(s) === 'string' ? s.toLowerCase() : ;

const capitalize = compose(lower, upperCapital);

// Сравниваем суперпозицию и композицию функций

console.log(upperCapital(lower('MARCUS AURELIUS'))); console.log(capitalize('MARCUS AURELIUS')); </syntaxhighlight>Композиция произвольного кол-ва функций:<syntaxhighlight lang="javascript"> const compose = (...funcs) => (...args) => (

 funcs.reduce((args, fn) => [fn(...args)], args)

); </syntaxhighlight>

Асинхронная композиция[править]

В асинхронном программировании функции возвращают значения в колбеки, и композиция может быть осуществлена связыванием последоваельности асинхронных функций в цепочку колбеков, когда следующая функция становится колбеком для предыдущей (это последовательная композиция) или параллельная композиция, которая порождает функцию, завершающуюся при завершении всех колбеков из последовательности функций. <syntaxhighlight lang="javascript"> // вспомогательная функция асинхронный reduce const reduceAsync = (items, performer, done, initialValue) => {

 const nseted = initialValue === undefined;
 let counter = nseted ? 1 : 0;
 let previous = nseted ? items[0] : initialValue;
 let current = nseted ? items[1] : items[0];
 function response(err, data) {
   if (!err && counter !== items.length - 1) {
     ++counter;
     previous = data;
     current  = items[counter];
     performer(previous, current, response, counter, items);
   } else if (done) {
     done(err, data);
   }
 }
 performer(previous, current, response, counter, items);

};

// асинхронная композиция // funcs - array of parametrs for functions // args - array of functions // args[i] - function // args[-1] - done(err, data) // const composeAsync = (funcs, ...args) => (

 () => reduceAsync(
   args.slice(0, -1),
   (params, fn, done) => fn(...[].concat(params).concat(done)),
   args[args.length - 1],
   funcs
 )

); </syntaxhighlight>

Ссылки[править]