rootsaga - redux saga tutorial
Saga Redux asincrónica/espera patrón (3)
Estoy usando async / await en mi código base. Debido a esto, mis llamadas api están definidas por funciones asíncronas
async function apiFetchFoo {
return await apiCall(...);
}
Me gustaría llamar a esta función desde el código de mi saga. Parece que no puedo hacer esto:
// Doesn''t work
function* fetchFoo(action) {
const results = await apiFetchFoo();
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
Sin embargo, esto funciona, y coincide con la documentación de la saga de redux:
// Does work
function* fetchFoo(action) {
const results = yield call(apiFetchFoo);
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
¿Es esta la forma correcta de usar Redux Saga junto con async / await? ¿Es estándar usar esta sintaxis del generador dentro del código de la saga, y el patrón asincrónico / de espera en otra parte?
Como señaló Josep, la await
no se puede utilizar dentro de un generador. En su lugar, necesita utilizar una función asíncrona . Además, tenga en cuenta que esto es una limitación de la propia función asíncrona. No se impone por redux-saga.
Más allá de esto, también quería mencionar que es una elección consciente por parte de los autores de la saga redux para no permitir que los desarrolladores expresen sagas como funciones async/await
.
Los generadores son más poderosos que async/await
y permiten funciones avanzadas de redux-saga como la coordinación de tareas paralelas .
Además, expresar sagas como generadores nos ayuda a definir los redux-saga.js.org/docs/basics/DeclarativeEffects.html que son objetos simples que definen el efecto secundario. Los efectos hacen que sea muy fácil probar nuestras sagas .
Entonces, aunque su código de trabajo está bien, tal vez no sea una buena idea mezclar sagas y funciones asíncronas.
Simplemente defina su apiFetchFoo
para devolver una promesa que se resuelva con la respuesta a la solicitud. Y cuando esto suceda tu saga se reanudará con los results
.
const apiFetchFoo = () =>
fetch(''foo'')
.then(res => res.json())
Sí, esa es la forma estándar de usar Redux-Saga.
Nunca debe llamar a la función de await
directamente dentro del saga-generator, porque redux-saga es para orquestar los efectos secundarios. Por lo tanto, cada vez que desee ejecutar un efecto secundario, debe hacerlo produciendo el efecto secundario a través de un efecto de redux-saga
(generalmente: call
o fork
). Si lo haces directamente sin producirlo a través de un efecto redux-saga
, redux-saga
no podrá orquestar el efecto secundario.
Si lo piensas bien, el generador de redux-saga es completamente comprobable sin la necesidad de burlarse de nada. Además, ayuda mantener las cosas desacopladas: si su apiFetchFoo
devolviera una promesa, la saga seguiría funcionando igual.
await
siempre trabaja dentro de una función que está declarada como async
. #regla del pulgar
async function fetchList () {
let resp = await fetchApi([params]);
}