Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.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
Javascript 如何在redux saga中取消正在运行的网络请求?_Javascript_Reactjs_Axios_Redux Saga - Fatal编程技术网

Javascript 如何在redux saga中取消正在运行的网络请求?

Javascript 如何在redux saga中取消正在运行的网络请求?,javascript,reactjs,axios,redux-saga,Javascript,Reactjs,Axios,Redux Saga,我有一个传奇故事: function* sagaOne() { yield call(apiOne); yield call(apiTwo); yield call(apiThree); } function* sagaTwo() { try { yield all(users.map((user) => call(sagaOne, user)); yield put(successAction); } catch (err) {

我有一个传奇故事:

function* sagaOne() {
   yield call(apiOne);
   yield call(apiTwo);
   yield call(apiThree);
}

function* sagaTwo() {
   try {
      yield all(users.map((user) => call(sagaOne, user));
      yield put(successAction);
   } catch (err) {
     yield put(errAction);
   }
}

function* sagaThree() {
   const task = yield fork(sagaTwo);
   yield take(CancelAction);
   yield cancel(task);
}
我的问题是-当
sagaThree
开火时,它会分叉
sagaTwo
。如果我调度cancel操作并且
sagaOne
已处于更深的状态-
apiOne
调用已解决并且
apiTwo
已启动,则整个请求不会被取消

问题:当一个“更深层次的”、“嵌套的”任务(sagaOne)已经处于第二产量或第三产量时,如何正确地取消它? 总结:只有在启动后立即取消任务并且两个
apiTwo中没有一个尚未启动时,取消才有效。如果进行得更深,取消就不起作用,每个
sagaOne
中的每个调用都会解决

对于返回承诺结果的函数,您可以通过在承诺中附加
[CANCEL]
来插入自己的取消逻辑

有关取消redux saga任务的详细信息

因此,我们需要使用一个方法来丰富axios返回的承诺,该方法将在取消时由redux saga调用,并将取消传出的xhr请求。您可以找到相关的axios文档

好的,让我们将此应用于api调用:

import axios from 'axios';
import { CANCEL } from 'redux-saga'

const CancelToken = axios.CancelToken;

const apiOne = () => {
  const source = CancelToken.source();
  const promise = axios.post('url', {
    cancelToken: source.token
  });

  promise[CANCEL] = () => source.cancel();
  return promise;
};
现在,一旦
sagaOne
被取消,api调用也将被取消(当然,如果它还没有完成的话)



这是基本思想。您可以将公共逻辑提取到包装器或适配器中,所以不需要在每个api函数中都这样做。您还可以通过将executor函数传递给
CancelToken
构造函数来创建一个cancel令牌。

您正在询问如何取消api调用?这取决于api调用的实现方式。是fetch、xhr还是axios之类的库?取消sagas效果很好,请参见此处:。。。如果您谈论的是API请求本身,那么一旦调用了API,请求就会完成。这是一个浏览器的东西,不是saga的东西。@MartinKadlec不准确,一旦saga被取消,你们实际上可以取消api请求。如何做取决于什么是“api请求”@AlekseyL。这是一个邮寄请求。如何取消它?请为api调用添加示例代码,如上所述-这取决于您如何执行