Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Lidando com Efeitos Colaterais com Redux Saga
Search
Filipe Costa
May 13, 2017
Programming
230
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Lidando com Efeitos Colaterais com Redux Saga
Filipe Costa
May 13, 2017
More Decks by Filipe Costa
See All by Filipe Costa
Pitch - Lidando com Efeitos Colaterais com Redux Saga
filipebarcos
0
400
Rust for Rubysts
filipebarcos
2
260
Limpando Seu Código JS Com O Padrão Pub/Sub
filipebarcos
0
200
Tu trabalha em casa?? Que moleza hein!
filipebarcos
0
130
Rediscovering OOP in Rails World
filipebarcos
0
100
jQuery Bad Practices
filipebarcos
2
270
Intro to Ruby
filipebarcos
1
140
Other Decks in Programming
See All in Programming
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
3.9k
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
230
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
240
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
280
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
2
640
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
240
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
160
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
160
CSC307 Lecture 17
javiergs
PRO
0
320
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
260
Inside Stream API
skrb
1
710
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
300
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
560
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
210
Are puppies a ranking factor?
jonoalderson
1
3.5k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
250
Docker and Python
trallard
47
3.9k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
Code Review Best Practice
trishagee
74
20k
Prompt Engineering for Job Search
mfonobong
0
340
Transcript
Lidando com Efeitos Colaterais com Redux Saga @filipebarcos
Redux
"Evolui ideias do Flux, mas evita suas complexidades pegando dicas
do Elm" — github.com/reactjs/redux Redux
Redux UI Reducer Store Action dispatched (currentState, action) => newState
New State
Pausa Dramática
O que é uma Função Pura?
"É uma função em que seus parâmetros são a única
coisa que influenciam no seu valor de retorno"
"É uma função em que seus parâmetros são a única
coisa que influenciam no seu valor de retorno" — eu
Redux UI Reducer Store Action dispatched (currentState, action) => newState
New State
Redux UI Middleware Reducer Store Action dispatched (currentState, action) =>
newState New State Action forwarded Action dispatched
Redux Saga
github.com/redux-saga/redux-saga
E o que é uma “Saga”?
None
“…a sequence of transactions that can be interleaved with other
transactions.” http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf — Hector Garcia-Molina e Kenneth Salem
“…a sequence of transactions that can be interleaved with other
transactions.” http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf — Hector Garcia-Molina e Kenneth Salem
“…a saga is like a separate thread in your application
that's solely responsible for side effects.” — https://github.com/redux-saga/redux-saga
Como eu é possível parar uma execução de uma função
em JS?
JS Generator Functions*
ES6 Feature
https://davidwalsh.name/es6-generators http://2ality.com/2015/03/es6-generators.html
https://davidwalsh.name/es6-generators function* foo(x) { const y = 2 * (yield
(x + 1)); const z = yield (y / 3); return (x + y + z); } const it = foo(5); // note: not sending anything into `next()` here console.log(it.next()); // { value:6, done:false } console.log(it.next(12)); // { value:8, done:false } console.log(it.next(13)); // { value:42, done:true }
Alguns exemplos
https://redux-saga.github.io/redux-saga/docs/basics/UsingSagaHelpers.html import { call, put } from 'redux-saga/effects'; export function*
fetchData(action) { try { const data = yield call(Api.fetchUser, action.payload.url); yield put({type: 'FETCH_SUCCEEDED', data}); } catch (error) { yield put({type: 'FETCH_FAILED', error}); } } function* watchFetchData() { yield takeEvery('FETCH_REQUESTED', fetchData); }
https://redux-saga.github.io/redux-saga/docs/basics/UsingSagaHelpers.html import { takeEvery } from 'redux-saga'; // FETCH_USERS function*
fetchUsers(action) { ... } // CREATE_USER function* createUser(action) { ... } // use them in parallel export default function* rootSaga() { yield takeEvery('FETCH_USERS', fetchUsers); yield takeEvery('CREATE_USER', createUser); }
E os testes?
import { call, put } from 'redux-saga/effects'; export function* fetchData(action)
{ try { const data = yield call(Api.fetchUser, action.payload.url); yield put({type: 'FETCH_SUCCEEDED', data}); } catch (error) { yield put({type: 'FETCH_FAILED', error}); } } function* watchFetchData() { yield takeEvery('FETCH_REQUESTED', fetchData); } https://redux-saga.github.io/redux-saga/docs/basics/UsingSagaHelpers.html
import { call, put } from 'redux-saga/effects'; export function* fetchData(action)
{ try { const data = yield call(Api.fetchUser, action.payload.url); yield put({type: 'FETCH_SUCCEEDED', data}); } catch (error) { yield put({type: 'FETCH_FAILED', error}); } } function* watchFetchData() { yield takeEvery('FETCH_REQUESTED', fetchData); } https://redux-saga.github.io/redux-saga/docs/basics/UsingSagaHelpers.html
{ CALL: { fn: Api.fetchUser, args: [“/users”], }, }
const generator = fetchData(); expect(generator.next()).toEqual({ done: false, value: call(Api.fetchUser, action.payload.url)
});
Tá, mas e aí?
redux-saga === redux-thunk + testabilidade
None
None
Ações Futuras
take x takeEvery
function* watchThis() { yield takeEvery('THIS', doThat); }
function* watchThis() { while(true) { yield take('THIS', doThat); } }
function* watchDeaths() { yield take('DIE', newTry); yield take('DIE', newTry); yield
take('DIE', put, { type: 'GAME_OVER' }); }
Chamadas “não-bloqueantes”
fork
function* mySaga() { while(true) { yield take(''); yield call(foo); yield
call(bar); } }
function* mySaga() { while(true) { yield take(''); yield fork(foo); yield
fork(bar); } }
Executar tarefas em paralelo
const [visits, registrations] = yield all([ call(fetch, '/visits'), call(fetch, '/registrations')
]);
Corrida entre efeitos colaterais
const { posts, timeout } = yield race({ posts: call(fetch,
'/posts'), timeout: call(delay, 1000) });
Composição de Sagas
yield*
function* foo() { ... } function* bar() { ... }
function* baz() { ... } function* fooBarBaz() { yield* foo(); yield* bar(); yield* baz(); }
tests?
tests?
function* foo() { ... } function* bar() { ... }
function* baz() { ... } function* fooBarBaz() { yield call(foo); yield fork(bar); yield call(baz); }
Cancelamento de Tarefas
function* mySync() { try { while(true) { yield put({type: 'SYNC_STARTED'});
const result = yield call(syncMyFiles); yield call(delay, 500); } } finally { if (yield cancelled()) yield put({ type: 'SYNC_STOPED'}); } } function* myDropbox() { while(yield take('START_FILE_SYNC')) { const mySyncTask = yield fork(mySync); yield take('STOP_FILE_SYNC'); // this will cause the forked task to jump into its finally block yield cancel(mySyncTask); } }
gist.github.com/filipebarcos/ 0a137d6ca837c117f999958a365fc5b6
Obrigado. @filipebarcos