コードベース全体でasync/awaitを使用しています。このため、私のAPI呼び出しは非同期関数によって定義されています
async function apiFetchFoo {
return await apiCall(...);
}
この関数を私のサガコードから呼び出したいです。私はこれを行うことができないようです:
// Doesn't work
function* fetchFoo(action) {
const results = await apiFetchFoo();
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
ただし、これは機能し、redux sagaのドキュメントと一致します。
// Does work
function* fetchFoo(action) {
const results = yield call(apiFetchFoo);
yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
これはasync/awaitと一緒にRedux Sagaを使用する正しい方法ですか?サガコード内でこのジェネレーター構文を使用し、他の場所でasync/awaitパターンを使用するのが標準ですか?
はい、それがRedux-Sagaを使用する標準的な方法です。
Redux-sagaはorchestratingの副作用のためであるため、await
関数をsaga-generator内で直接呼び出すことはできません。したがって、副作用を実行したいときはいつでも、redux-saga
効果(通常:call
またはfork
)を介して副作用を発生させて実行する必要があります。 redux-saga
効果を使用せずに直接実行すると、redux-saga
は副作用を調整できません。
考えてみると、redux-sagaジェネレーターは、モックを作成することなく完全にテスト可能です。また、物事を分離した状態に保つのに役立ちます。apiFetchFoo
がプロミスを返した場合、サガは同じように機能します。
Josepが指摘したように、await
はジェネレーター内で使用できません。代わりに、 async function を使用する必要があります。また、これは非同期機能自体の制限であることに注意してください。 redux-sagaによるものではありません。
これを超えて、私はそれが 意識的な選択 redux-saga作者によるnotによる開発者の許可であることにも言及したかったasync/await
関数としてsagasを表現します。
ジェネレーターはasync/await
よりも強力で、 co-ordinating parallel tasks などのredux-sagaの高度な機能を使用できます。
さらに、sagaをジェネレーターとして表現することで、副作用を定義する単純なオブジェクトである Effects を定義できます。効果により、 サガのテストが非常に簡単 になります。
したがって、作業コードは問題ありませんが、sagaと非同期関数を混同しないことをお勧めします。
apiFetchFoo
を定義するだけで、リクエストへの応答で解決されるプロミスを返します。そして、これが起こると、あなたの物語はresults
から再開します。
const apiFetchFoo = () =>
fetch('foo')
.then(res => res.json())
await
は、async
として宣言されている関数内で常に機能します。 #thumbRule
async function fetchList () {
let resp = await fetchApi([params]);
}