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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
480
3Dシーンの圧縮
fadis
1
770
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
170
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
280
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
130
JavaDoc 再入門
nagise
1
340
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
2
670
Vite+ Unified Toolchain for the Web
naokihaba
0
300
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
230
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
540
New "Type" system on PicoRuby
pocke
1
920
Featured
See All Featured
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
390
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
230
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
350
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Amusing Abliteration
ianozsvald
1
200
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
780
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Leo the Paperboy
mayatellez
7
1.8k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
360
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
160
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
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