Частичное применение функций в JavaScript | OTUS

Частичное применение функций в JavaScript

otus_Posts_25may_VK_1000x700_1-5020-980880.jpg

Частичное применение функций — один из лучших механизмов, когда-либо созданных для совместного использования кода. Он позволяет внедрять зависимости в код, не прибегая ко всем типичным ООП-шаблонам.

В нашем примере мы будем оборачивать библиотеку Axios. Это печально известная библиотека, а известна она тем, что выдаёт исключения вместо того, чтобы возвращать ошибочный ответ. С подобными библиотеками работать довольно сложно, особенно применяя async/await.

Чтобы сделать безопасной небезопасную функцию, нам пригодится карринг и частичное использование функций:

// Оборачиваем axios, чтобы обеспечить безопасный вызов api без отбрасывания исключений
const safeApiCall = ({ url, method }) => data =>
  axios({ url, method, data })
    .then( result => ([null, result]) ) 
    .catch( error => ([error, null]) );

// Частично применяем общую функцию выше, чтобы работать с пользовательским API
const createUser = safeApiCall({
    url: '/api/users',
    method: 'post'
  });

// Теперь безопасно вызываем API и не беспокоимся об исключениях
const [error, user] = await createUser({
  email: '[email protected]',
  password: 'Password'
});

Посмотрите, что функцию safeApiCall мы записываем как func = (params) => (data) => {...}. Это техника распространена в функциональном программировании и именно её называют карринг. И именно она идёт рука об руку вместе с частичным применением функций. Что это значит? То, что функция func при вызове с params возвратит другую функцию, которая по факту и выполняет работу. Иначе говоря, функция частично используется с params.

Мы можем записать это следующим образом:

const func = (params) => (
   (data) => {...}
);

Посмотрите, что зависимости (params) передаются в качестве первого параметра, а фактические данные передаются в качестве второго параметра.

Если требуется упрощение задачи, допускается применение npm-пакета saferr, который тоже способен работает с промисами и async/await:

import saferr from "saferr";
import axios from "axios";

const safeGet = saferr(axios.get);

const testAsync = async url => {
  const [err, result] = await safeGet(url);

  if (err) {
    console.error(err.message);
    return;
  }

  console.log(result.data.results[0].email);
};


// Вывод: [email protected]
testAsync("https://randomuser.me/api/?results=1");

// Вывод: Network Error
testAsync("https://shmoogle.com");

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто