Разработка в изоляции

Alexey Raspopov, DataRobot.

Разработка в изоляции

Разработка с ограничениями

Disclaimer

Данный контент является проекцией личного опыта и переживаний автора. Может вызывать возгорание в определенных местах организма. Слайды наполнены кодом, местами с богомерзким React'ом, ES6 и функциональщиной.

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

Кто я?

λ

Композиция — серебрянная пуля!

Композиция

(лат. compositio — связывание, сложение, соединение) — составление целого из частей.

Композиция функций — применение результата одной функции к вычислению результата другой.

Композиция объектов — составление объекта на основе других.

f(g(a))

Interactive & Reactive

Interactive & Reactive

			// interactive
			const data = getData(param);
			process(data);
		
			// reactive
			getData(param)
			  .then(data => process(data));
		

Interactive (pull)

			function getCompanyByUser(userId) {
			  const user = getUser(userId);
			  const company = getCompany(user.companyId);
			 
			  return company;
			}
		

Reactive (push)

			function getCompanyByUser(userId) {
			  return getUser(userId)
			    .then(user => getCompany(user.companyId));
			}
		

Interactive > Reactive

А что если?

Асинхронные операции с интерактивным синтаксисом!

Сопрограмма

(англ. coroutine) — подпрограмма имеющая несколько входных точек. На практике реализуется с помощью конечного автомата, который, в свою очередь, реализуется с помощью генератора.

Генератор

(англ. generator) — рутина (подпрограмма) которая может генерировать последовательность значений (по требованию). Создает итератор.

Итератор (англ. iterator) — объект предоставляющий последовательный доступ к элементам коллекции.

Генератор

			function* fib() {

			

			
		

Использование генератора

			const gen = fib();
			gen.next(); // { value: 1, done: false }
			gen.next(); // { value: 1, done: false }
			gen.next(); // { value: 2, done: false }
			gen.next(); // { value: 3, done: false }
			gen.next(); // { value: 5, done: false }
			gen.next(); // { value: 8, done: false }
		

npm i co

Interactive, sync

			function getCompanyByUser(userId) {
			  const user = getUser(userId);
			  const company = getCompany(user.companyId);
			 
			  return company;
			}
		

Interactive, async

			const getCompanyByUser = co.wrap(function* (userId) {
			  const user = yield getUser(userId);
			  const company = yield getCompany(user.companyId);
			 
			  return company;
			});
		

Данный код работает в современных браузерах без транспиляции.

async/await

npm i regenerator

npm i babel
babel-runtime

Interactive, sync

			function getCompanyByUser(userId) {
			  const user = getUser(userId);
			  const company = getCompany(user.companyId);
			 
			  return company;
			}
		

Interactive, async

			async function getCompanyByUser(userId) {
			  const user = await getUser(userId);
			  const company = await getCompany(user.companyId);
			 
			  return company;
			}
		

a => f(g(a))

async a =>
f(await g(a))

Основная идея

Снизу вверх

			fetch = url => new Promise(...);
			getUser = userId => fetch(`/users/${userId}`);
			getFriends = async ids => await* ids.map(getUser);
			
		

Преимущества

Хорошо!
Что делать с объектами?

npm i react

Сорян))

Почему так?

Самый маленький компонент

			UserInfo = ({user, onSelect}) =>
			  <article onClick={onSelect} role="listitem">
			    <p>{user.name}</p>
			    <p><em>{user.isOnline}</em></p>
			  </article>
		

Композиция

			UsersList = ({users, onSelect}) =>
			  <section>
			    {users.map(user => 
			      <UserInfo
			        key={user.id}
			        user={user}
			        onSelect={onSelect} />)}
			  </section>
		

И еще на уровень выше

			FriendsPage = ({userId}) => {
			  const friends = getFriends(userId);
			 
			  <div>
			    <h2>Friends</h2>
			    <UsersList users={friends} onSelect={openPage} />
			  </div>
			}
		

Стоп! Что?

И еще на уровень выше

			async FriendsPage = ({userId}) => {
			  const friends = await getFriends(userId);
			 
			  <div>
			    <h2>Friends</h2>
			    <UsersList users={friends} onSelect={openPage} />
			  </div>
			}
		

A Mathematical Theory of Communication

npm i retransmitter

import Transmitter
from 'retransmitter'

Синхронный компонент

			Project = ({data}) =>
			  <article>
			    <p>{data.name}</p>
			    <p>{data.createdAt}</p>
			  </article>
		

Web API

			API.getProject = projectId =>
			  fetch(`/projects/${projectId}`)
		

Асинхронный компонент

			async ProjectPage = ({projectId}) => {
			  const project = await API.getProject(projectId);
			 
			  return <Project data={project} />
			}
		
export default Transmitter.wrap(ProjectPage)

Redux?

npm uninstall react-redux

npm i rx

И снова атомарный компоненты

			Todo = ({todo, onStatusChange}) =>
			  <article role="listitem">
			    <p>{todo.title}</p>
			    <input
			      type="checkbox"
			      checked={todo.done} onChange={onStatusChange} />
			  </article>
		

Список

			TodoList = ({todos, onStatusChange}) =>
			  <section>
			    {todos.map(todo =>
			      <Todo key={todo.id}
			        todo={todo} onStatusChange={onStatusChange} />
			    )}
			  </section>
		

Контейнер (TodoListContainer)

			export default Transmitter.create(TodoList, {
			  fragments: {
			    todos() {
			      return Transmitter.fromStore(TodoStore);
			    },
			    onStatusChange: () => TodosActions.updateTodo,
			  }
			})
		

<TodoListContainer />

О чем я вообще?

Проекты

Ссылки

Спасибо

Ссылка на эти слайды —
alexeyraspopov.github.io/development-in-isolation