【问题标题】:Redux-saga is stuck on yield callRedux-saga 卡在 yield call
【发布时间】:2016-06-23 20:15:30
【问题描述】:

我尝试在节点 6.2.1 上运行下一个代码。它记录 1, 2, 然后卡住了。我无法理解为什么它不继续执行到行 yield take('TEST')... 似乎 anotherSaga 完成并记录 2 但控制权没有返回给 rootSaga。谁能帮帮我?

const {runSaga, delay} = require('redux-saga');
const {take, put, call} = require('redux-saga/effects');

function* anotherSaga() {
  yield call(delay, 1000);
  console.log(2);
}

function* rootSaga() {
  while(true) {
    console.log(1);
    yield call(anotherSaga);
    console.log(3);
    const action = yield take('TEST');
    console.log(4);
    yield put(action);
  }
}

runSaga(
  rootSaga(),
  {
    subscribe(callback) {
      return setInterval(() => (callback({type: 'TEST'})), 1000);
    },
    dispatch(action) {
      console.log(action);
    },
    getState() {}
  }
);

更新:但没有 runSaga 的代码按预期工作,记录 1,2,3,4

const {createStore, applyMiddleware} = require('redux');
const createSagaMiddleware = require('redux-saga').default;
const {delay} = require('redux-saga');
const {take, put, call} = require('redux-saga/effects');

function* anotherSaga() {
  yield call(delay, 2000);
  console.log(2);
}

function* rootSaga() {
  while(true) {
    console.log(1);
    yield call(anotherSaga);
    console.log(3);
    const action = yield take('TEST');
    console.log(4);
    yield put(action);
    console.log('---')
  }
}

const rootReducer = (state, action) => {
  if (state === undefined) {
    return {};
  }

  return state;
}

const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, {}, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(rootSaga);

setInterval(() => (store.dispatch({type: 'TEST'})), 1000);

【问题讨论】:

  • 你在没有 runSaga 的情况下尝试过这段代码吗?
  • @kuy 我试过了,它按预期工作。请查看主题中的代码。

标签: javascript redux redux-saga


【解决方案1】:

看起来这是由于subscribe 函数没有返回正确的值。上面它返回setInterval 的结果,这将是间隔的ID。相反,它应该返回一个 redux-saga 可以用来取消订阅事件的函数,根据 docs。所以你的subscribe 函数应该看起来更像这样:

subscribe(callback) {
  const intervalId = setInterval(() => (callback({type: 'TEST'})), 1000);
  return () => { clearInterval(intervalId); };
},

用这个运行它,我可以看到它循环打印

1
2
3
4
{ type: 'TEST' }

这很奇怪这如何导致你的 saga 卡住,但我假设没有从 subscribe 接收到 unsubscribe 函数会导致 redux-saga 内部的事情变得混乱。

【讨论】:

  • 非常感谢!我错过了。但请注意 yelouafi added on github 仅返回 clearInterval 是不够的。 "订阅功能必须支持注册多个订阅。"
  • 我认为它实际上会起作用,因为特定订阅的 intervalId 将在我们构建的 unsubscribe 函数创建的闭包中捕获。因此,您可以多次调用 subscribe 并使用它们返回的函数分别取消订阅它们(因为每个函数都将绑定到正确的 intervalId)。
猜你喜欢
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多