Redux Saga中的依赖异步调用

时间:2017-05-24 17:38:55

标签: reactjs react-redux redux-saga

我正在学习Redux Saga,而且大部分都是有道理的。但是,我遇到的情况似乎是更好的实施。

我需要通过POST请求向第三方网站提交订单。为了提交订单,我首先需要向不同的端点发出GET请求,以检索POST请求所需的一些信息。也就是说,POST请求取决于成功返回的GET请求。

我目前的工作解决方案如下所示:

function* create(action) {
  try {
    const code = yield axios.get('/url/to/code?id=XXXXX'`);
    const order = {...some_object, code: code.data}
    const result = yield axios.post('/url/to/order', order);
    yield put({...action, type: CREATE_SUCCESS, data: result.data});
  } catch (e) {
      const errors = e.response.data;
      yield put({...action, type: CREATE_FAIL, errors: errors});
    }
  }

有没有推荐的方法在Redux Saga中处理这个问题?

我的一个想法是将每个请求移动到自己的操作中,然后GET操作将调度POST操作。寻找关于如何做到这一点的输入' Saga'办法。

1 个答案:

答案 0 :(得分:4)

我不确定是否存在此类官方最佳做法,但我会尝试根据官方文档展示代码中可以改进的内容。

让我们阅读redux-saga readme的第一行:

  

redux-saga是一个旨在产生副作用的库(即   在React / Redux应用程序中,异常事件,如数据获取和不正确的事情,如访问浏览器缓存),   更好。

好的,你在这里进行异步数据获取。我们将讨论它。

redux-saga最好的一点是它如何让您轻松进行测试。现在很难测试你的传奇,因为你直接打电话给axios()。你必须以某种方式模拟/间谍axios或设置假的服务器等。

这就是为什么你应该使用axios方法call包裹redux-saga的原因,例如

import { call, put } from 'redux-saga/effects';

function* create(action) {
  try {
    const code = yield call(axios.get, '/url/to/code?id=XXXXX');
    const order = {...some_object, code: code.data}
    const result = yield call(axios.post, '/url/to/order', order);
    yield put({...action, type: CREATE_SUCCESS, data: result.data});
  } catch (e) {
    const errors = e.response.data;
    yield put({...action, type: CREATE_FAIL, errors: errors});
  }
}

现在测试上面的代码应该非常直接。

在redux-saga文档的Basic concepts -> Declarative Effects中对此进行了详细描述。我们来自docs的例子:

确保工作但不是那么正确:

function* fetchProducts() {
  const products = yield Api.fetch('/products')
  // ...
}

正确的方法,更容易测试:

function* fetchProducts() {
  const products = yield call(Api.fetch, '/products')
  // ...
}

它也非常开明,强烈建议阅读上面的整篇链接文章。

  

与前面的例子不同的是,现在我们不是   立即执行获取调用,而调用创建一个   效果的描述。

让我们回到你问题的第二部分:

  

我的一个想法是将每个请求移动到自己的行动中,然后是   GET操作将调度POST操作。寻找关于如何的输入   这就是'Saga'的方式。

很难说是否将此作为一个单独的传奇分裂,为了提出请求而调度另一个动作是否有意义。

与往常一样,一切都取决于您的应用程序需求和上下文,可能最好的方法是回答以下问题:您是否在其他地方提出相同的请求?您是否必须在应用程序的不同部分之间共享该请求中涉及的逻辑?您是否需要取消或重试机制?