在 react redux saga 中处理同步
Handle Sync in react redux saga
用户将输入姓名电子邮件和订单信息,包括付款详情。
单击表单中的“立即购买”按钮后,我计划执行以下步骤:
- 通过 api 调用创建用户。
- 自动登录并获取令牌
api呼唤。
- 使用表单数据通过 api 调用创建订单。
- 通过 api 调用获取支付提供商令牌。
- 进入支付页面。
前端使用 React-redux-saga。
请在下方输入代码:
function* addToCartCamp(action) {
try {
// User creation and login
yield put({ type: authActions.AUTH_REGISTER_REQUEST, ...createUser });
yield put({ type: authActions.AUTH_REGISTER_SUCCESS, ...userdata });
yield put({ type: authActions.AUTH_LOGIN_REQUEST, ...login });
//Create order
const { data } = yield orderAPI.addToCartCamp(action);
yield put({ type: orderActions.ADD_TO_CART_SUCCESS, ...data });
yield put({ type: orderActions.GET_DETAIL_ORDER_REQUEST, ...{orderId: order_id} });
//Handle Payment
if(action.payment.method === 'creditCard'){
yield put({ type: orderActions.TOKEN_REQUEST, ...{orderId: order_id} });
} else{
yield put({ type: orderActions.BANK_TRANSFER_REQUEST, ...{orderId: order_id} });
}
} catch (error) {
// handle error message
}
}
我可以在 saga 文件中调用多个 Yield put 然后 api 吗?调用此函数时,后台甚至在创建用户和登录之前就开始创建订单过程。
我需要所有进程 运行 同步,但它们 运行 目前处于异步状态。
传奇和反应的新手。如何处理?
tl;dr:您需要 take()
一个动作并且 call()
api 在 [=14= 之前产生结果]正在执行成功操作。
例子
function* addToCartCamp(action) {
try {
const action = yield take(authActions.AUTH_REGISTER_REQUEST);
const userToCreate = action.payload;
const userData = yield call(authApi.createUser, userToCreate);
yield put({ type: authActions.AUTH_REGISTER_SUCCESS, userData });
const sessionData = yield call(authApi.loginUser, userData);
yield put({ type: authActions.AUTH_LOGIN_SUCCESS, sessionData });
// ...
}
}
补充说明
在我看来,你在一个传奇故事中发生的事情太多了。为什么要在创建订单的同一个地方注册用户?我会将这两个用例分成两个不同的故事,因为您可能有一个已经注册的用户,只需要在购买之前登录即可。不要在您的订单传奇中处理身份验证,让 API 处理身份验证失败。
说到这里,您还应该对 api 次调用失败采取措施。因此,当服务器 returns 一个 401 因为用户未被授权去购物时,你应该 yield put
一个特定的 orderActions.SOMETHING_FAILURE
操作与一个 reducer 存储错误消息,处理挂起状态等。
拥有全局 try catch 块会使调试变得非常困难,应该避免。请参阅 https://github.com/redux-saga/redux-saga/blob/master/docs/basics/ErrorHandling.md(最后一个代码示例):
import Api from './path/to/api'
import { call, put } from 'redux-saga/effects'
function fetchProductsApi() {
return Api.fetch('/products')
.then(response => ({ response }))
.catch(error => ({ error }))
}
function* fetchProducts() {
const { response, error } = yield call(fetchProductsApi)
if (response) {
yield put({ type: 'PRODUCTS_RECEIVED', products: response })
} else {
yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
}
}
用户将输入姓名电子邮件和订单信息,包括付款详情。 单击表单中的“立即购买”按钮后,我计划执行以下步骤:
- 通过 api 调用创建用户。
- 自动登录并获取令牌 api呼唤。
- 使用表单数据通过 api 调用创建订单。
- 通过 api 调用获取支付提供商令牌。
- 进入支付页面。
前端使用 React-redux-saga。
请在下方输入代码:
function* addToCartCamp(action) {
try {
// User creation and login
yield put({ type: authActions.AUTH_REGISTER_REQUEST, ...createUser });
yield put({ type: authActions.AUTH_REGISTER_SUCCESS, ...userdata });
yield put({ type: authActions.AUTH_LOGIN_REQUEST, ...login });
//Create order
const { data } = yield orderAPI.addToCartCamp(action);
yield put({ type: orderActions.ADD_TO_CART_SUCCESS, ...data });
yield put({ type: orderActions.GET_DETAIL_ORDER_REQUEST, ...{orderId: order_id} });
//Handle Payment
if(action.payment.method === 'creditCard'){
yield put({ type: orderActions.TOKEN_REQUEST, ...{orderId: order_id} });
} else{
yield put({ type: orderActions.BANK_TRANSFER_REQUEST, ...{orderId: order_id} });
}
} catch (error) {
// handle error message
}
}
我可以在 saga 文件中调用多个 Yield put 然后 api 吗?调用此函数时,后台甚至在创建用户和登录之前就开始创建订单过程。
我需要所有进程 运行 同步,但它们 运行 目前处于异步状态。
传奇和反应的新手。如何处理?
tl;dr:您需要 take()
一个动作并且 call()
api 在 [=14= 之前产生结果]正在执行成功操作。
例子
function* addToCartCamp(action) {
try {
const action = yield take(authActions.AUTH_REGISTER_REQUEST);
const userToCreate = action.payload;
const userData = yield call(authApi.createUser, userToCreate);
yield put({ type: authActions.AUTH_REGISTER_SUCCESS, userData });
const sessionData = yield call(authApi.loginUser, userData);
yield put({ type: authActions.AUTH_LOGIN_SUCCESS, sessionData });
// ...
}
}
补充说明
在我看来,你在一个传奇故事中发生的事情太多了。为什么要在创建订单的同一个地方注册用户?我会将这两个用例分成两个不同的故事,因为您可能有一个已经注册的用户,只需要在购买之前登录即可。不要在您的订单传奇中处理身份验证,让 API 处理身份验证失败。
说到这里,您还应该对 api 次调用失败采取措施。因此,当服务器 returns 一个 401 因为用户未被授权去购物时,你应该 yield put
一个特定的 orderActions.SOMETHING_FAILURE
操作与一个 reducer 存储错误消息,处理挂起状态等。
拥有全局 try catch 块会使调试变得非常困难,应该避免。请参阅 https://github.com/redux-saga/redux-saga/blob/master/docs/basics/ErrorHandling.md(最后一个代码示例):
import Api from './path/to/api'
import { call, put } from 'redux-saga/effects'
function fetchProductsApi() {
return Api.fetch('/products')
.then(response => ({ response }))
.catch(error => ({ error }))
}
function* fetchProducts() {
const { response, error } = yield call(fetchProductsApi)
if (response) {
yield put({ type: 'PRODUCTS_RECEIVED', products: response })
} else {
yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
}
}