Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redux Saga异步/等待模式_Redux_React Redux_Redux Saga - Fatal编程技术网

Redux Saga异步/等待模式

Redux Saga异步/等待模式,redux,react-redux,redux-saga,Redux,React Redux,Redux Saga,我在整个代码库中使用async/await。因此,我的api调用由异步函数定义 async function apiFetchFoo { return await apiCall(...); } 我想从我的saga代码中调用这个函数。看来我做不到这一点: // Doesn't work function* fetchFoo(action) { const results = await apiFetchFoo(); yield put({type: "FOOS_FETCHED_SU

我在整个代码库中使用async/await。因此,我的api调用由异步函数定义

async function apiFetchFoo {
  return await apiCall(...);
}
我想从我的saga代码中调用这个函数。看来我做不到这一点:

// 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代码中使用这个生成器语法是标准的,在其他地方使用异步/等待模式是标准的?

是的,这是使用Redux saga的标准方法

您不应该直接在saga生成器中调用
wait
函数,因为redux saga是用于协调副作用的。因此,任何时候想要产生副作用,都应该通过
redux saga
效应产生副作用(通常是:
call
fork
)。如果你不通过
redux-saga
效果直接进行,那么
redux-saga
将无法协调副作用


仔细想想,redux saga生成器是完全可测试的,无需模仿任何东西。此外,它还有助于保持事情的解耦:如果您的
apiFetchFoo
返回了一个承诺,那么这个传奇仍然可以继续工作。

wait
始终在声明为
async
的函数中工作#拇指尺

async function fetchList () {
  let resp = await fetchApi([params]);
}

正如Josep所指出的,
await
不能在发电机内部使用。相反,您需要使用一个。另外,请注意,这是异步函数本身的一个限制。它不是由redux传奇强加的

除此之外,我还想指出,redux saga的作者不允许开发人员将saga表示为
async/await
函数,这是一个错误

生成器比
async/await
更强大,它们支持redux saga之类的高级功能

此外,将传奇表达为生成器有助于我们定义哪些是定义副作用的简单对象。效果让它变得更有趣

所以,尽管您的工作代码很好,但最好不要将sagas和异步函数混为一谈

只需定义您的
apiFetchFoo
,以返回一个承诺,该承诺将与对请求的响应一起解析。当这种情况发生时,您的传奇故事将以
结果
继续

 const apiFetchFoo = () =>
   fetch('foo')
     .then(res => res.json())

奇怪的是,在异步/等待模式中,为什么要使用
函数*(){…等待}
而不是
异步函数(){..等待}
?我敢肯定,如果您在不使用async的情况下使用await,会导致一个错误“await是一个保留的javascript关键字”。小提示:如果您使用的是TypeScript和typedefs,并且您将函数定义为异步函数,如下所示:
async function*fetchFoo(action:requestAction):AsyncGenerator{
,则需要包含
“es2018.asynciterable”
到您的tsconfig的
编译器选项.lib
数组,如果您还没有。另外,我需要TypeScript 3.7(从3.0开始)。您是否可以在讨论的地方包括任何文档或github问题的链接?如果OP想要等待一个没有副作用的承诺,该怎么办?这似乎是异步生成器的一个有效用例,但Redux Saga似乎不允许它们。@ModuleTos肯定!恐怕您我不太明白redux saga是关于什么的。redux saga生成器是用来协调副作用的。如果你想做你所提到的事情,那么你不应该在redux saga生成器中这样做…你可以在普通生成器中这样做-如果你想的话-或者在另一个承诺中,这并不重要…然后只生成一个<代码>调用redux传奇生成器内部的效果,该生成器调用promise/generator/whatever。啊,是的,这是有道理的!我想我误解了redux传奇生成器的边界,并试图让它做得比它应该做的更多。相反,我应该等待“无副作用”“在实体中的承诺,该承诺将产生传奇。仅供参考(可能帮助他人),下面是来自
react saga
文档的一个很好的解释,解释了为什么我们不应该在saga中直接调用异步函数:。根据该文档,saga应该对saga中间件产生效果,saga中间件将执行效果并将结果交还给saga。效果是简单的JS对象告诉中间件,该怎么办。这种让saga中间件产生效果的想法使saga的单元测试变得简单,而不需要模拟API调用之类的异步内容。可爱的是:redux saga生成器完全可以测试,无需模拟任何东西