question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple `takeLatest` in saga root ?

See original GitHub issue

I can’t have several takeLatest in my saga root, it’s normal ?

export default function* root() {
  yield* takeLatest(Actions.LOGIN, login);
  yield* takeLatest(Actions.LOGOUT, logout);
}

Only the one takeLatest is take into account 😕

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:3
  • Comments:15 (10 by maintainers)

github_iconTop GitHub Comments

26reactions
yelouaficommented, Feb 17, 2016

@Grmiade yield* allows only for sequential compositions; see http://yelouafi.github.io/redux-saga/docs/advanced/SequencingSagas.html

If you want to yield muliple tasks in parallel (note yield and not yield*)

export default function* root() {
  yield [
     takeLatest(Actions.LOGIN, login),
     takeLatest(Actions.LOGOUT, logout)
  ]
}

It works because takeLatest and takeEvery return Iterators, and redux-saga can also handle yielding iterators directly. But this has a minor side effect on monitoring Sagas (the Saga monitor will print anonymous on the places you call yield);

If you’ve worked before with languages like C/C++ you can view the difference between direct call (yield iterator) and delegation (yield* iterator) like the difference between calling a function and a marco in your code.

Using yield takeLatest is like calling a function, the middleware will run the Iterator and resumes the parent Saga when the iterator terminates (in the above case the parent Saga will resume when all the child iterators in the array terminates)

Using delegation (yield*) the Iterator will be spread into the parent Saga: It’s like if you replaced the body of the parent Saga by the instructions of the invoked iterator. So in you code example

export default function* root() {
  yield* takeLatest(Actions.LOGIN, login);
  yield* takeLatest(Actions.LOGOUT, logout);
}

The body of root will run the first takeLatest until it terminates, then only will run the second.

16reactions
yelouaficommented, Feb 17, 2016

@slorber from the order of execution POV there is no diff. But when testing root it makes a difference

For example, if we have

function* child() {
  yield 1
  yield 2
}

Using yield* child() will delagate all next calls to child

export default function* root() {
  yield* child()
  yield* child()
}

// testing
iter = root()
iter.next().value // => 1
iter.next().value // => 2
iter.next().value // => 1
iter.next().value // => 2

Using yield only evaluate and returns the expression

export default function* root() {
  yield child()
  yield child()
}

// testing
iter = root()
iter.next().value // => result of child() => an iterator
iter.next().value // => result of child() => an iterator

when you yield an iterator directly like in yield takeLatest(...), the middleware autoamtically resolves the yielded iterator (like it does with Promises): it runs it and waits for it to terminate and possibly return a value. But testing raw iterators could be difficult (like testing raw promises)

When you use the delegation form yield* takeLatest() all the yields in the child are ‘copied’ into the parent Saga;

Read more comments on GitHub >

github_iconTop Results From Across the Web

Redux Saga Watch Multiple Action - Stack Overflow
it watches LOAD_SEARCHRESULTS action and then calls getSearchResults function. Is there any way I can watch multiple actions in root? Something ...
Read more >
Concurrency - Redux-Saga
takeLatest doesn't allow multiple Saga tasks to be fired concurrently. As soon as it gets a new dispatched action, it cancels any previously-forked...
Read more >
How to Handle Multiple Sagas in Redux Saga - YouTube
Learn how to handle multiple sagas in Redux Saga. Most React apps will have more than one saga so you will have to...
Read more >
How to wait for 2 actions to dispatch another? - Redux Saga
... in redux-saga, next I will explain step by step how to get this. ... default function* rootSaga() { yield takeLatest("INITIAL_ACTION", ...
Read more >
[Solved]-Redux Saga Watch Multiple Action-Reactjs
takeLatest can also take an array of actions, so you just need to do export default function* root() { yield takeLatest([LOAD_SEARCHRESULTS, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found