我有个故事:
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中的每个调用都会解决。
发布于 2020-06-29 05:20:29
对于返回允诺结果的函数,可以通过将
[CANCEL]附加到允诺来插入自己的取消逻辑。
更多关于取消剩余-传奇任务这里的信息。
因此,我们需要用一种方法丰富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构造函数来创建取消令牌。
https://stackoverflow.com/questions/62592384
复制相似问题