在不同的动作上采取相同的传奇/史诗动作

时间:2018-06-13 11:27:58

标签: redux redux-thunk redux-saga redux-observable

我是关于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,我做了这个,但它不起作用。它在每次更改时调用getData函数,延迟为1秒。

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())
  );
};

有没有人有任何想法或意见来实现这一目标?

1 个答案:

答案 0 :(得分:1)

如果没有经过测试,我认为你可以写一个这样的解决方案:

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。因此,虽然onFormUpdate位于delay然后取消,但下一步({1}}将不再被调用。