【问题标题】:Dispatch action every X second using Redux Saga使用 Redux Saga 每 X 秒调度一次动作
【发布时间】:2016-10-12 19:25:12
【问题描述】:

作为 redux-saga 的新手,我正在尝试设置一个 saga,它对动作 LANGUAGE_START_CYCLE 做出反应,并每 3 秒循环一次动作 LANGUAGE_CYCLE

但是当我将LANGUAGE_START_CYCLE 发送到 Redux 商店时,传奇 LANGUAGE_CYCLE 从未像我预期的那样运行。

知道我做错了什么吗?我怀疑这是一个简单的错误,因为我的其他 sagas 运行良好。

// constants/ActionTypes.js
export const LANGUAGE_SET_ACTIVE = "LANGUAGE_SET_ACTIVE";
export const LANGUAGE_START_CYCLE = "LANGUAGE_START_CYCLE";
export const LANGUAGE_STOP_CYCLE = "LANGUAGE_STOP_CYCLE";
export const LANGUAGE_CYCLE = "LANGUAGE_CYCLE";


// actions/language.js
export const cycleLanguage = () => {
    return {
        type: ActionTypes.LANGUAGE_CYCLE
    }
};    

// languageSaga.js
import { actionChannel, call, take, put, race } from 'redux-saga/effects'
import * as ActionTypes from '../constants/ActionTypes';
import * as actions from '../actions/language';

const wait = ms => {
    new Promise(resolve => {
        setTimeout(() => resolve(), ms)
    })
};

export default function * languageSaga() {
    const channel = yield actionChannel(ActionTypes.LANGUAGE_START_CYCLE);
    while (yield take(channel)) {
        while (true) {
            const { stopped } = yield race({
                wait: call(wait, 3000),
                stopped: take(ActionTypes.LANGUAGE_STOP_CYCLE)
            });

            if (!stopped) {
                yield put(actions.cycleLanguage());
            } else {
                break;
            }
        }
    }
}


// sagas.js (root sagas)
export default function * sagas() {
    yield [
        directorySaga(), // Another saga which works fine
        pusherSaga(), // Another saga which works fine
        languageSaga()
    ]
}

我的其他 sagas 之一的示例,它们正在运行:

// directorySaga.js
function * fetchDirectory(action) {
    try {
        const directory = yield call(Api.fetchDirectory, action.id);
        yield put(fetchDirectorySucceeded(directory));
    } catch (e) {
        yield put(fetchDirectoryFailed(e.message));
    }
}

export default function * directorySaga() {
    yield * takeLatest(ActionTypes.DIRECTORY_REQUESTED, fetchDirectory);
}

【问题讨论】:

  • 抱歉,您并没有真正说出这里出了什么问题,因此很难为您提供帮助。你发送什么,你期望什么,你得到什么?
  • 问题是当我发送LANGUAGE_START_CYCLE 时,传奇并没有运行我的比赛效果。我试图到处尝试/捕捉,但没有任何输出。有关如何更好地解决此问题的任何提示?
  • 放置日志并告诉哪些打印或不打印。我什至不知道你是否会进入那里的循环:)
  • 哇,刚刚做了一些观察。我要自己回答这个问题,你会感到惊讶(也许):-)

标签: javascript reactjs redux redux-saga


【解决方案1】:

我将在这里回答我的问题。

上面的代码我工作了,但是当我触发动作时,我使用Redux Dev Tools 将动作分派到商店。

我使用工具手动发送 LANGUAGE_START_CYCLE,这改变了状态 - 但显然这并没有通知 saga 中间件并且我的频道从未更新:

但是当在我的一个组件中使用一个简单的按钮时:

<button onClick={() => dispatch(actions.startCycle())}>
    Start
</button>
<button onClick={() => dispatch(actions.stopCycle())}>
    Stop
</button>

通知 saga 中间件。

更新

我的店铺配置是:

import { createStore, applyMiddleware, compose } from 'redux'
import createSagaMiddleware from 'redux-saga';
import rootReducer from '../reducers/index';
import sagas from '../sagas/index';

export default function configureStore(initialState) {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(rootReducer, initialState, compose(
    applyMiddleware(sagaMiddleware),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  ));

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers');
      store.replaceReducer(nextReducer);
    });
  }

  sagaMiddleware.run(sagas);

  return store;
}

【讨论】:

  • 我可以看看您是如何创建商店的吗?这可能是因为使用了错误的中间件排序
  • 您应该尝试总是最后声明 saga 中间件。它实际上将首先应用(应用程序列表颠倒)。在您的情况下,您传递给 devtools 的商店还没有被 saga 增强,这意味着从 devtools 调度是 Redux 的原始 dipatch,没有任何中间件
  • 您应该按照您希望中间件处理的顺序注册中间件。从 thunk/async/promise/... 开始,中间 devtools,最后一个 saga。
  • 如果我这样做 const store = createStore(rootReducer, initialState, compose( window.devToolsExtension ? window.devToolsExtension() : f =&gt; f, applyMiddleware(sagaMiddleware) )); sagas 不工作?
【解决方案2】:

我认为等待函数的类型错误。 你必须像这样修复。

const wait = ms => {
  return new Promise(resolve => {  
    setTimeout(() => resolve(), ms)  
  })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2012-03-14
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 2019-02-01
    相关资源
    最近更新 更多