如何间隔地调用redux-saga?

时间:2019-03-08 22:10:57

标签: redux-saga

我需要间隔获取数据。目前,我使用React组件容纳逻辑并仅渲染null,但我向我的应用程序添加了redux-saga,我希望将流程移至saga。我一直无法弄清楚如何进行生成器回调或从回调中调用生成器。

这是我到目前为止构建的:

// @flow
import { takeLatest, all, put, select } from 'redux-saga/effects';
import * as types from '../constants/ActionTypes';

let timers: Array<IntervalID> = [];

const getUpdateInterval = (state) => state.settings.updateInterval;

const createTimer = (callback: Generator<any, any, any>, interval: number = 120) => {
  return setInterval(() => {
    callback.next();
  }, interval * 1000);
}

export default function * data (): Generator<any, any, any> {
  yield all([
    takeLatest(types.AUTHENTICATE_SUCCEEDED, fetchData),
    takeLatest(types.AUTHENTICATE_SUCCEEDED, setupTimers),
    takeLatest(types.AUTHENTICATE_FAILED, clearTimers),
    takeLatest(types.LOGGED_OUT, clearTimers)
  ]);
}

function * fetchData () {
  yield put({type: types.FETCH_DATA});
}

function * setupTimers () {
  const updateInterval = yield select(getUpdateInterval);

  clearTimers();

  const newTimer = createTimer(function * () {
    yield fetchData();
  }, updateInterval);

  timers.push(newTimer);
}

function clearTimers () {
  timers.forEach(clearInterval);
  timers = [];
}

2 个答案:

答案 0 :(得分:2)

  

我一直无法弄清楚如何进行生成器回调或从回调中调用生成器。

我怀疑如果您将redux-saga和回调结合使用,您的代码将最终变得很棘手。对于这种情况,如何使用delay

function* callInAnInterval (fn) {
  while (yield select(shouldFetch)) {
    yield call(fn)
    const updateInterval = yield select(getUpdateInterval);
    yield delay(updateInterval)
  }

}

答案 1 :(得分:0)

export function* watchGetSomething() {
    yield takeEvery(GET_SOMETHING, getSomethingFlow);
}

function* getSomethingFlow({offset, limit}: IGetSomething) {
    try {
        do {
            const result = yield call(Api.getSomething, offset, limit);
            yield put(setSomething(result.data.payload));
            yield delay(60 * 1000);
        } while (true);
    } catch (e) {
        yield put(putSnackbarMessage(SOMETHING_GET_ERROR));
    }
}