redux - 在不同的动作上使用 takeLatest 来限制相同的传奇/史诗动作
问题描述
我是 redux-saga/observable 的新手。但我无法处理看起来非常适合这些的场景。所以; 如果表单发生任何更改,我想调用 API。但由于性能原因,我不想大量调用 API。
基本上,当我触发 SLIDERCHANGED、TEXTBOXCHANGED、CHECKBOXCHECKED 时,我还想调用 getData 函数。但我需要延迟检查其他操作。例如; 如果 SLIDERCHANGED 被触发,它应该等待 1sn,如果此时触发 TEXTBOXCHANGED,它将被取消并等待 1sn 更多调用 getData 函数。所以这就是我尝试实现 Redux-saga 或 redux-observable 的原因。
我有动作类型;
const SLIDERCHANGED = 'APP/sliderchanged';
const TEXTBOXCHANGED = 'APP/textboxchanged';
const CHECKBOXCHECKED = 'APP/checkboxchecked';
const LOADING = 'APP/loading';
const LOADDATA = 'APP/loaddata';
const ERRORLOADDATA = 'APP/errorloaddata';
我也有行动;
export function updateSliderValue(val) {
return { type: SLIDERCHANGED, val };
}
export function updateTextboxValue(val) {
return { type: TEXTBOXCHANGED, val };
}
export function updateCheckboxValue(val) {
return { type: CHECKBOXCHECKED, val };
}
export function loading() {
return { type: LOADING };
}
export function loadData(data) {
return { type: LOADDATA, data };
}
export function errorLoadData(err) {
return { type: ERRORLOADDATA, err };
}
export function getData(vehicleInfo) { // redux-thunk ASYNC function
return (dispatch, getState) => {
dispatch(loading());
return dispatch(apiCall('/getAllData', {}))
.then(payload => {
dispatch(loaddata(payload));
})
.catch(error => {
dispatch(errorLoadData(error));
});
};
}
使用 redux-saga,我做到了,但它不起作用。它以 1sn 延迟在每次更改时调用 getData 函数。
import { put, throttle } from 'redux-saga/effects';
import {
SLIDERCHANGED,
TEXTBOXCHANGED,
CHECKBOXCHECKED
} from './constants';
import { getData } from './actions';
function* onFormUpdate() {
yield put(getData());
}
export function* watchFormChange() {
yield throttle(
10000,
[SLIDERCHANGED, TEXTBOXCHANGED, CHECKBOXCHECKED],
onFormUpdate
);
}
使用 redux-observable,不知何故我也得到了同样的错误。
import { ofType } from 'redux-observable';
import { delay, map, debounceTime } from 'rxjs/operators';
import {
SLIDERCHANGED,
TEXTBOXCHANGED,
CHECKBOXCHECKED
} from './constants';
import { getData } from './actions';
export const onFormUpdate = action => {
return action.pipe(
ofType(SLIDERCHANGED, TEXTBOXCHANGED, CHECKBOXCHECKED),
debounceTime(1000),
map(() => getData())
);
};
有没有人有任何想法或意见来实现这一点?
解决方案
未经测试,我认为您可以编写如下解决方案:
import { delay } from 'redux-saga'
import { put } from 'redux-saga/effects'
function* onFormUpdate() {
yield delay(1000)
yield put(getData())
}
export function* watchFormChange() {
yield takeLatest(
[SLIDERCHANGED, TEXTBOXCHANGED, CHECKBOXCHECKED],
onFormUpdate,
)
}
这里的想法是,一旦三个动作中的另一个被调度,takeLatest
它将立即取消。onFormUpdate
所以 while onFormUpdate
is indelay
然后被取消,下一步,即put
,将不再被调用。
推荐阅读
- init - 在创建类时python调用用户定义的__init__的cpython源代码中
- azure-data-lake-gen2 - azure datalake gen2 中的 SQL 数据
- java - 为什么索引访问比 Java 中的链接访问快?
- nestjs - 清理嵌套请求的最佳方法
- c++ - 有没有办法使用重载运算符作为比较的一部分
- python - 有没有办法为熊猫数据框编写带有 groupby 子句的自定义累积聚合函数?
- python - 将一个表中的随机数据插入另一个表中的现有行
- excel - 将数字从 Excel 单元格转换为 IEEE 754 十六进制格式
- c++ - C++ 知道成员函数是否被调用
- java - 从 JNI 代码中使对象引用为空