【发布时间】:2021-01-10 22:19:40
【问题描述】:
今天刚学redux-saga,我读到的是takelatest会取消同一个请求,只执行最新的请求,但我的代码似乎没有这样做,每次我点击获取按钮时,它都会附加一个新请求而没有取消上一个,希望有人能解释一下原因,谢谢。
【问题讨论】:
标签: reactjs redux redux-saga
今天刚学redux-saga,我读到的是takelatest会取消同一个请求,只执行最新的请求,但我的代码似乎没有这样做,每次我点击获取按钮时,它都会附加一个新请求而没有取消上一个,希望有人能解释一下原因,谢谢。
【问题讨论】:
标签: reactjs redux redux-saga
它将取消 saga,但这只是意味着它不会恢复 saga(除非进入 finally 块,如果有的话)。如果还有其他需要拆解的事情,例如取消 axios 网络请求,那么您需要自己添加代码。例如:
function* getPeople() {
const cancelTokenSource = axios.CancelToken.source();
try {
const { data } = yield axios.request({
method: 'get',
url: 'http://localhost:3004/people',
cancelToken: cancelTokenSource.token
});
yield put(actions.setPeople(data));
} catch (e) {
yield put(actions.setPeopleError({
type: 'get_data',
message: e.message
});
} finally {
if (yield cancelled()) {
cancelTokenSource.cancel();
}
}
}
还有另一种选择。当你向 redux-saga 产生一个 Promise 时,如果该 Promise 上有一个特殊的属性,那么 redux-saga 会在 saga 被取消时自动调用该属性。因此,如果您发现自己经常取消 axios 网络请求,您可以设置一个辅助方法,将该属性添加到您的 axios 承诺中:
import { CANCEL } from 'redux-saga';
const req = () => {
const cancelTokenSource = axios.CancelToken.source();
const promise = axios.request({
method: 'get',
url: 'http://localhost:3004/people',
cancelToken: cancelTokenSource.token
});
promise[CANCEL] = () => cancelTokenSource.cancel();
return promise;
}
function* getPeople() {
try {
const { data } = yield call(req);
yield put(actions.setPeople(data));
} catch (e) {
yield put(actions.setPeopleError({
type: 'get_data',
message: e.message
});
}
}
【讨论】: