Redux-Saga 行为模式

Redux-Saga behavior pattern

这样的故事非常成功:

function* getPosition() {
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    console.log(`I am getPosition: ${pos.coords.latitude}, ${pos.coords.longitude}`);
  });
}

但我需要 Redux 状态树中的坐标。因此,我尝试了一些模式,其中 none 行得通。 1) 无法从 getCurrentPosition 范围

中获取变量
function* getPosition() {
  let position = {};
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    position = pos;
  });
  // either
  console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
  // or
  yield console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
  // Any of two is undefined
}

2)没有办法return和赋值:

function* getPosition() {
  const position = yield navigator.geolocation.getCurrentPosition(function(pos) {
    return pos;
  });
  yield console.log(`I am getPosition: ${position.coords.latitude}, ${position.coords.longitude}`);
}

3) put方法无效:

function* getPosition() {
  yield navigator.geolocation.getCurrentPosition(function(pos) {
    // Pos fetched
    console.log(`I am getPosition: ${pos.coords.latitude}, ${pos.coords.longitude}`);
    // Nothing happens. State is empty object.
    put({
      type: LOCATION_SET_POSITION,
      pos
    });
  });
}

locationReducer 在 rootReducer 内部,因为其他工作的 reducer 是:

locationReducer.js
export function locationReducer(state = {}, action) {
  switch (action.type) {
    case LOCATION_SET_POSITION:
      return action.pos
    default:
      return state;
  }
}

而且我没有actionCreater。据我了解,put 方法都 调度一个动作并设置 actionCreator。 如何将坐标放入状态树?

你的问题是 geolocation.getCurrentPosition 是异步的,但是在 success/error 回调风格中,而你需要它是一个被提供给 redux-saga

的承诺
function* getPositionSaga() {
    const getCurrentPosition = () => new Promise(
      (resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject)
    )
    const pos = yield call(getCurrentPosition)
    yield put({type: LOCATION_SET_POSITION, pos})
}

这里我们将 getCurrentPosition 包装成一个 return 是 Promise<Position>

的函数

call 是一个 redux-saga 效果,如果给它的函数 return 一个承诺,它只会在那个承诺被履行时产生,并且 return 履行为您的 saga 增加价值以供进一步使用。

put 是一个最终会通过 redux

调度给定动作对象的效果

任何 redux-saga 效果必须从生成器产生而不是直接调用,因为它们 return 只是 redux-saga 中间件执行器的一个简单指令对象(而不是实际执行副作用立即地)。执行者只能在从生成器产生时访问和控制它们,因此在回调中使用它们(如您的示例 3)将不会像您期望的那样工作