Сага о yield
Скрытые возможности
Нажми пробел чтобы продолжить
Стрелка вправо — для быстрой промотки
Веб-сервис МойМеханик
Автомеханик приедет к вам домой и на работу
Redux + Riot.js
3 месяца
Agile
3 программиста
Чем хорош Flux
3. Многоразовые компоненты
2. Просто отладить
1. Легко понять
Как работает
страница
корзины ?
// on button click
function onCancel(){
store.dispatch({
type: 'ORDER_UPDATE_CANCEL_REQUESTED',
orderId
})
}
// on button click
function onSubmit(){
updateOrder({
orderId,
onSuccess: updateQuote,
})
}
function updateQuote(orderId){
store.dispatch({
type: 'INSTANT_QUOTE_REQUESTED',
orderId
})
let request = fetchAPI('/quote/update', {
userId,
orderId
})
// ...
}
request.then(function(data){
if (data.status == 4000005){
store.dispatch({type: 'USER_LOGOUT'})
store.dispatch({type: 'AUTH_REQUESTED'})
}
})
Готово !
А где работа с <form></form>?
Где fetchOrder() ?
Где window.location = '/payment' ?
1. Разбит на части и переплетен
Каков код на вкус?
2. Непонятно где начало, где конец
3. Сделать еще одно приложение ― для мастеров
Хорошие новости!
1. Упаковать сайт в формат виджета для сайтов партнеров
2. Упаковать в PhoneGap приложение
Будущее проекта
прекрасно!
Естественная запись кода
Что делает страница заказа?
1. отобразить прелоадер
2. загрузить заказ с сервера
3. показать форму заказа
4. дождаться ввода пользователя
5. отправить данные на сервер
6. отобразить ошибки
7. repeat until
// 1. отобразить прелоадер
mountPage('preloader-page')
// 2. загрузить заказ с сервера
let response = yield fetch(`/order/${id}`)
// 3. показать форму заказа
let pageChannel = mountPage('order-page')
let order = yield response.json()
store.dispatch({
type: 'ORDER_FETCHED',
payload: order
})
// 4. дождаться ввода пользователя
let formData = yield take(pageChannel)
// 5. отправим данные на сервер
let response = yield fetch(`/order/${id}`,{
method: 'POST',
body: JSON.stringify(formData),
})
let errors = yield response.json()
if (!errors.length)
return window.location = '/payment'
// 6. отобразить ошибки
store.dispatch({
type: 'ERRORS_OCCURRED',
errors
})
// 7. repeat until
// TODO обернуть код в while(true){}
// Поместить весь код в function*(){}
yield & coroutines
function* runAndWait() {
console.log('Готов к работе')
let serverData = yield {
command: 'waitForServerResponse',
promise: fetch('/orders'),
}
// ...
}
let userData = yield {
command: 'waitForUserInput',
}
- Запускаешь
- Обрабатываешь события
- Останавливаешь
Coroutine
Как аналог процесса
Redux-saga
yield promiseObj
yield take(channel)
let task = yield fork(coroutine)
yield join(task)
yield cancel(task)
Песочница
/catalog
function* runCatalogPage
/cart
function* runCartPage
function* updateOrder
/payment
function* runCatalogPage
function* updateQuote
Исключения ♡ Декораторы
--> function* handleCommonAPIErrors
----> function* runCartPage
------> function* fetchAPI
--------> throw new APIError({code: 500002})
function decorate(coroutine){
function* wrappedCoroutine(){
try {
yield* coroutine()
} catch(error) {
// handle error
}
}
return wrappedCoroutine
}
const wrappedRunCartPage = decorate(runCartPage)
OrderNotFound
try {
yield* runPage()
} catch(exception) {
if (exception instanceof OrderNotFound){
mountPage('order-not-found')
}
// ...
LoginRequired
try {
yield* runPage()
} catch(exception) {
if (exception instanceof LoginRequired){
window.location = '/signin'
}
// ...
}
Что-то пошло не так
try {
yield* runPage(...args)
} catch(exception) {
Raven.captureException(exception)
mountPage('error-page')
}
Шаблоны без сайд-эффектов
Store
React
== Model
== View + Controller
Store
React
Coroutine
select
channel.put
View
Controller
Что это дало проекту МойМеханик ?
-
способность наращивать функционал
-
в коде легко ориентироваться
-
меньше бойлерплейта
-
Hot Module Replacement
С чего начать ?
- Еще примеры кода: slides.com/pelid80/redux-saga
- Примеры кода на GitHub: pelid/redux-saga-demo
- Документация по redux-saga
- Заменить роутер на проекте
Ищу людей в OpenSource проект
Напишите мне pelid80@gmail.com
Спасибо!
Какие есть вопросы?
Автор доклада: Евгений Евсеев
CTO веб-сервиса МойМеханик.рф
email pelid80@gmail.com
skype evseev.evgeny
Сага о yield
By Evgeny Evseev
Сага о yield
- 1,183