Redux Saga异步/等待模式

时间:2017-04-17 00:37:26

标签: redux react-redux redux-saga

我在整个代码库中使用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模式是标准的吗?

3 个答案:

答案 0 :(得分:26)

是的,这是使用Redux-Saga的标准方法。

你永远不应该直接在saga-generator中调用await函数,因为redux-saga用于编排副作用。因此,每当您想要运行副作用时,您应该通过redux-saga效果(通常为callfork)产生副作用。如果您直接执行此操作而不通过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]);
}