reactjs - 在 react redux saga 中处理同步

标签 reactjs synchronization react-redux yield redux-saga

用户将输入姓名电子邮件和订单信息,包括付款详情。 单击表单中的“立即购买”按钮后,我计划执行以下步骤:

  • 通过 API 调用创建用户。
  • 自动登录并获取 token API 调用。
  • 使用表单数据通过 API 调用创建订单。
  • 通过 API 调用获取支付提供商 token 。
  • 进入支付页面。

前端使用 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 吗?当调用此函数时,后端甚至在用户创建和登录之前就开始订单创建过程。

我需要所有进程同步运行,但它们当前以异步方式运行。

saga 和 React 的新手。如何处理?

最佳答案

tl;dr:您需要take() 一个 Action 并call() api 以在 之前产生结果put()成功操作。

例子

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 调用失败采取措施。因此,当服务器因用户无权购物而返回 401 时,您应该 yield put 特定的 orderActions.SOMETHING_FAILURE 操作和存储错误消息的 reducer,处理挂起状态等。

拥有全局 try catch block 会使调试变得非常困难,应该避免。参见 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 })
  }
}

关于reactjs - 在 react redux saga 中处理同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52541410/

相关文章:

reactjs - 如何让 Next Image 组件与 Storybook 一起工作

javascript - 在 REACT 中构建 GridView

reactjs - facebook 喜欢 React JS 中的通知和 redux 依赖通知图标?

javascript - 更改后 react redux 表单更新原始

javascript - Reactjs - 未捕获的类型错误 : Cannot read property 'then' of undefined

reactjs - React/Redux 测试错误 : The initialState argument passed to createStore is of unexpected type

git - 跨计算机同步 git 存储库

java - 线程有自己的数据副本吗?

java - 如何使用等待队列监视器实现简单的线程同步

javascript - 异步调用 axios API 后使用 React hook 和 redux 设置状态