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)将不会像您期望的那样工作
这样的故事非常成功:
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)将不会像您期望的那样工作