Дросселирование одной и той же саги / эпического действия с помощью takeLatest для разных действий - PullRequest
0 голосов
/ 13 июня 2018

Я новичок в редуксе-саге / наблюдаемых вещах.Но я не мог справиться со своим сценарием, который выглядит так хорошо на них.Так;Я хочу вызвать 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));
        });
  };
}

СРедукс-сага, я сделал это, но это не работает.Он вызывает функцию 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
  );
}

При наличии наблюдаемой редукции. Также почему-то я получаю ту же ошибку.

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 голосов
/ 18 июня 2018

Не протестировав его, я думаю, что вы можете написать решение, подобное этому:

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 и затем отменяется, следующий шаг, который является put, больше не будет вызываться.

...