J'utilise async/wait tout au long de ma base de code. A cause de cela, mes appels api sont définis par des fonctions asynchrones.
async function apiFetchFoo {
return await apiCall(...);
}
Je voudrais appeler cette fonction de mon code de saga. Il semble que je ne peux pas faire ça:
// Doesn't work
function* fetchFoo(action) {
const results = await apiFetchFoo();
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
Cependant, cela fonctionne et correspond à la documentation de la saga redux:
// Does work
function* fetchFoo(action) {
const results = yield call(apiFetchFoo);
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
Est-ce la bonne façon d'utiliser Redux Saga aux côtés de async/wait? Il est standard d’utiliser cette syntaxe de générateur dans le code de la saga, et le modèle async/wait ailleurs?
Oui, c'est la manière standard d'utiliser Redux-Saga.
Vous ne devriez jamais appeler la fonction await
directement à l'intérieur du générateur de saga, car redux-saga est destiné à orchestrant les effets secondaires. Par conséquent, chaque fois que vous souhaitez utiliser un effet secondaire, vous devez le faire en utilisant l'effet redux-saga
(généralement: call
ou fork
). Si vous le faites directement sans céder avec un effet redux-saga
, alors redux-saga
ne pourra pas orchestrer l'effet secondaire.
Si vous y réfléchissez, le générateur redux-saga est complètement testable sans avoir besoin de vous moquer de rien. En outre, il est utile de garder les choses découplées: si votre apiFetchFoo
retournait une promesse, la saga fonctionnerait toujours de la même manière.
Comme Josep l'a fait remarquer, await
ne peut pas être utilisé à l'intérieur d'un générateur. Au lieu de cela, vous devez utiliser un fonction async. . Notez également qu’il s’agit d’une limitation de la fonction async. Il n'est pas imposé par redux-saga.
Au-delà de cela, je voulais également mentionner que c’est un choix conscient des auteurs de la saga redux-saga qui permet à not de permettre aux développeurs d’exprimer sagas sous forme de fonctions async/await
.
Les générateurs sont plus puissants que async/await
et permettent des fonctionnalités avancées de redux-saga comme coordination des tâches parallèles .
De plus, exprimer les sagas en tant que générateurs nous aide à définir Effets qui sont des objets simples définissant l'effet secondaire. Les effets le rendent très facile de tester nos sagas .
Donc, bien que votre code de travail soit correct, peut-être que ne pas confondre sagas et la fonction async est une bonne idée.
Il suffit de définir votre apiFetchFoo
pour renvoyer une promesse qui résout la réponse à la demande. Et lorsque cela se produira, votre saga reprendra avec la results
.
const apiFetchFoo = () =>
fetch('foo')
.then(res => res.json())
await
travaille toujours dans une fonction déclarée async
. #thumbRule
async function fetchList () {
let resp = await fetchApi([params]);
}