我试图按顺序产生一系列传奇效果。这个想法是它将并行yield all([call(foo), call(bar])
运行(或者至少以伪并行方式)。call(foo)
call(bar)
但是,我希望我的传奇按顺序运行,这意味着我想在启动之前等待foo
结束bar
(这样我可以取消该过程)。
这个调用数组是动态生成的,所以我可以硬写一系列的yield
. 在这种情况下,正确的语法是什么?
我在这里面临一个复杂的问题,非常感谢您的帮助。当我导航到应用程序的不同页面时,某些服务响应错误,并且我在不同页面中看到该错误。例如,假设我想买东西,为此我调用一个处理此任务的传奇。然后我立即注销,并在登录中看到错误。当我更改屏幕时,我想取消当前页面中运行的所有传奇故事。为了解决这个问题,我做了一个动作,当用户从一个屏幕切换到另一个屏幕时调度该动作。此操作正在调用生成器函数:
function* taskCancelHelper(actions, sagas) {
.....
}
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是如何“采取”当前屏幕中调度的所有预期操作并调用适当的传奇。我用了:
const action = take(action => [..actions in the current screen].indexOf(action.type) < 0); but it does not seem to work.
Run Code Online (Sandbox Code Playgroud)
然后我想将调度此操作时调用的所有传奇故事传递到数组中[上述操作的传奇故事]。我的想法是在我的 taskCancelHelper* 生成器函数中传递这两个数组,并使用 for 循环来取消每个任务:
For (i=0; i < actions.length; i++) {
yield cancel(sagas[i])
}
Run Code Online (Sandbox Code Playgroud)
您知道如何执行当前屏幕上调用传奇的所有操作吗?
我正在使用 sagas 上传不同数量的媒体文件。因此您可以动态添加更多媒体文件。我遇到的问题是,当文件上传而没有等待前一个文件完成时,以前调度的操作会丢失,然后会调度新的操作。基本上,这就像具有相同操作类型的 catch 的并发操作UPLOAD_ACTION
。
代码是这样的:
export default function* root() {
yield all([takeLatest(LOGIN_REQUEST, login), ..., takeLatest(UPLOAD_REQUEST, upload)]);
}
function* uploadSlide({payload}) {
try {
const response = yield call(
uploadApi,
payload
);
yield put({type: SUCCESS, payload: response});
} catch (error) {
yield put(type: FAILURE);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过不同的替代方案,例如使用takeEvery
或 a channel
,但它们不起作用。
有什么建议么?
我有一个用户个人资料页面,用户可以在其中更新数据。提交数据后,应将其重定向到仪表板页面。
我的配置文件
handleProfileUpdate = () => {
let user = this.state;
this.props.updateUserProfile(user);
}
Run Code Online (Sandbox Code Playgroud)
动作定义如下
export const updateUserProfile = (obj) => ({
type: types.USER_PROFILE_UPDATE_REQUEST,
payload: obj
});
Run Code Online (Sandbox Code Playgroud)
Saga 文件定义如下。
function* updateUserProfile(action) {
try {
let data = action.payload;
yield call(userProvider.updateUserProfile, data);
// dispatch a success action to the store
yield put({ type: types.USER_PROFILE_UPDATE_SUCCESS, data });
yield put(push('/dashboard'));
yield put(constants.successMsg(userProfileUpdateSuccess));
} catch (error) {
// dispatch a failure action to the store with the error
yield put(constants.DEFAULT_ERROR_MSG);
}
}
export function* watchUserProfileUpdateRequest() …
Run Code Online (Sandbox Code Playgroud) 我有一个已经被调用并且必须等待的承诺。基本上:
const foo = () => Promise.resolve('foo'); // The real promise takes time to resolve.
const result = foo();
await result; // This line has to happen in the saga
Run Code Online (Sandbox Code Playgroud)
我如何等待未决的承诺?如果我将它包装在call
Redux Saga 中,则尝试调用它并崩溃。
在我的反应项目中,我有以下代码。
import uuid from 'uuid';
import { SET_ALERT, REMOVE_ALERT } from './types';
export const setAlert = (msg, alertType, timeout = 5000) => dispatch => {
const id = uuid.v4();
dispatch({
type: SET_ALERT,
payload: { msg, alertType, id }
});
setTimeout(() => dispatch({ type: REMOVE_ALERT, payload: id }), timeout);
};
Run Code Online (Sandbox Code Playgroud)
这里就用到了thunk。我将 saga 应用到项目中,我想用 saga 重写。由于没有 API 调用,我不想通过 saga 发送到减速器。我想从这个action直接转到reducer。那么如何在不发送的情况下重写呢?
在我的 React 项目中,我有以下代码:
export function* onDisplayAlert({ payload }: any) {
payload.id = getUniqueID();
yield put(setAlert(payload));
yield setTimeout(() => {
yield put(removeAlert(payload.id));
}, 3000);
}
Run Code Online (Sandbox Code Playgroud)
我想要在这里做的是使用yield
内部setTimeOut
回调。
yield put(removeAlert(payload.id));
Run Code Online (Sandbox Code Playgroud)
但是我写的方法不起作用,因为箭头函数回调不是生成器函数,所以我不能在其中使用yield。我如何在里面使用yield setTimeOut
?
我是redux-saga的初学者,我对以下情况感到困惑。我有一个 items 数组,我想为每个项目分叉相同的方法。所以我使用这行代码:
yield items.map(item => fork(loadItemDetails, item));
Run Code Online (Sandbox Code Playgroud)
使用上述代码,loadItemDetails
永远不会调用。相反,如果我fork
单独调用每个项目,如下所示,那么它会按预期工作。
yield fork(loadItemDetails, items[0]);
yield fork(loadItemDetails, items[1]);
yield fork(loadItemDetails, items[2]);
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,我无法弄清楚地图不起作用的原因。
我想在用户提交表单时设置表单加载状态(旋转图标,禁用输入),并在操作完成或失败时清除该状态。当前,我将这种状态存储在我的商店中,这涉及创建动作创建者和简化器,由于以下几个原因,这很烦人:
this.setState
本质上,我想在表单组件中执行此操作:
handleFormSubmitted() {
this.setState({ isSaving: true })
this.props.dispatchSaveForm({ formData: this.props.formData })
.finally(() => this.setState({ isSaving: false }))
}
Run Code Online (Sandbox Code Playgroud) 我第一次使用redux Saga处理我的API请求。我有一个异步函数,可以发送一个简单的发布请求,如下所示:
const onLoginRequest = async (userName, password) =>
await fetch(`${loginApi}`, { method: 'POST', body: { userName:userName,password:password } })
.then(res => res.json())
.then(res => res)
.catch(error => error);
Run Code Online (Sandbox Code Playgroud)
如果我在查询字符串中发送用户名和密码,则可以正常工作。但是,当将它们添加到我的POST正文中时,它大喊它们是未定义的。
知道我在做什么错吗?
redux-saga ×10
reactjs ×7
javascript ×6
redux ×4
generator ×2
react-native ×2
helper ×1
react-redux ×1
redux-thunk ×1
typescript ×1
yield ×1