我在整个代码库中使用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});
}
这是使用Redux Saga和async / await的正确方法吗?在saga代码中使用这个生成器语法,在其他地方使用async / await模式是标准的吗?
答案 0 :(得分:26)
是的,这是使用Redux-Saga的标准方法。
你永远不应该直接在saga-generator中调用await
函数,因为redux-saga用于编排副作用。因此,每当您想要运行副作用时,您应该通过redux-saga
效果(通常为call
或fork
)产生副作用。如果您直接执行此操作而不通过redux-saga
效果产生,则redux-saga
将无法协调副作用。
如果你考虑一下,redux-saga发生器是完全可测试的,不需要嘲笑任何东西。此外,它有助于保持事物分离:如果你的apiFetchFoo
返回了一个承诺,那么传奇仍然可以正常工作。
答案 1 :(得分:0)
正如Josep所指出的,await
不能在发电机内使用。相反,您需要使用async function。另请注意,这是异步功能本身的限制。它不是由redux-saga强加的。
除此之外,我还想提一下,由redux-saga作者提供的conscious choice 不允许开发者将sagas表达为async/await
函数。
生成器比async/await
更强大,它们允许使用redux-saga的高级功能,如co-ordinating parallel tasks。
此外,将sagas表示为生成器有助于我们定义Effects,它们是定义副作用的普通对象。效果使它成为very easy to test our sagas。
所以,虽然你的工作代码很好,但也许不会混淆传奇和异步功能是一个好主意。
只需定义您的apiFetchFoo
即可返回一个承诺,该承诺会根据对请求的响应进行解析。当发生这种情况时,你的传奇将继续results
。
const apiFetchFoo = () =>
fetch('foo')
.then(res => res.json())
答案 2 :(得分:-1)
await
始终在声明为async
的函数中工作。 #thumbRule
async function fetchList () {
let resp = await fetchApi([params]);
}