Redux Saga async/await pattern
Yes, that's the standard way to use Redux-Saga.
You should never be calling the await
function directly inside the saga-generator, because redux-saga is for orchestrating the side-effects. Therefore, any time that you want to run a side-effect you should do it by yielding the side-effect through a redux-saga
effect (usually: call
or fork
). If you do it directly without yielding it through a redux-saga
effect, then redux-saga
won't be able to orchestrate the side-effect.
If you think about it, the redux-saga generator is completely testable without the need of mocking anything. Also, it helps to keep things decoupled: if your apiFetchFoo
returned a promise, the saga would still work the same.
As pointed out by Josep, await
cannot be used inside a generator. Instead you need to use an async function. Also, note this is a limitation of async function itself. It is not imposed by redux-saga.
Beyond this, I also wanted to mention that it is a conscious choice by the redux-saga authors to not allow devs to express sagas as async/await
functions.
Generators are more powerful than async/await
and they allow advanced features of redux-saga like co-ordinating parallel tasks.
Moreover, expressing sagas as generators help us define Effects which are plain objects defining the side effect. Effects makes it very easy to test our sagas.
So, although your working code is fine, maybe not mixing up sagas and async function is a good idea.
Just define your apiFetchFoo
to return a promise which resolves with the response to the request. And when this happens your saga will resume with the results
.
const apiFetchFoo = () =>
fetch('foo')
.then(res => res.json())