【问题标题】:Handle Sync in react redux saga在 react redux saga 中处理同步
【发布时间】:2019-03-03 15:06:39
【问题描述】:

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

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

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

新的传奇和反应。怎么办?

【问题讨论】:

    标签: reactjs synchronization react-redux yield redux-saga


    【解决方案1】:

    tl;dr:您需要take() 一个动作和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 });
    
        // ...
      }
    }
    

    补充说明

    在我看来,你在一个传奇中发生了太多事情。为什么要在创建订单的同一个地方注册用户?我会将这两个用例分成两个不同的 saga,因为您可能有一个已经注册的用户,只需要在购买之前登录。不要在您的订单传奇中处理身份验证,让 API 处理身份验证失败。

    说到这里,你还应该有 api 调用失败的动作。因此,当服务器返回 401 时,因为用户无权购物,您应该 yield put 使用特定的 orderActions.SOMETHING_FAILURE 操作,其中包含存储错误消息、处理挂起状态等的减速器。

    拥有全局 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 })
      }
    }
    

    【讨论】:

    • 感谢您的建议。我将帐户创建和登录移动到页面中的不同按钮操作,然后休息到不同的按钮操作。现在可以顺利运行,没有任何问题。
    • 很高兴我能帮上忙。顺便说一句,如果我的回答解决了您的问题,您可以接受并投票赞成。
    最近更新 更多