2017-05-24 34 views
0

我在学习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}); 
    } 
    } 

是否有终极版佐贺来处理这一个推荐的方式?

我想到的一个想法是将每个请求转移到自己的操作中,然后GET操作将分派POST操作。寻找关于如何做这个'佐贺'的方法。

回答

3

我不确定是否存在这样的官方最佳实践,但我会尝试根据官方文档显示可以改进的代码。

让我们读出的第一线,从redux-saga readme

终极版,传奇是一个库,旨在使副作用(即 像数据获取和不纯之类的东西访问浏览器缓存异步的东西)反应/ Redux应用程序更容易,并且更好。

好的,你在这里做异步数据提取。我们会谈论它。

Reduce-saga中最好的事情之一就是它如何让你的测试变得轻松。现在将很难测试你的传奇,因为你直接拨打axios()。你将不得不嘲笑/间谍axios以某种方式或设置一个假服务器等

这就是为什么你应该call方法包装axiosredux-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中有很好的描述。让我们从文档的例子:

可以肯定的工作,但不是那么正确的做法:

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

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

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

它也很exaplained,强烈推荐阅读上面的整个链接文章。

从前面的例子不同的是,现在我们不 执行读取马上打电话,而是调用创建的效果 描述。

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

我有一个想法是每个请求转移到自己的行动,那么 GET行动将派遣POST操作。寻找输入如何 做这个'传奇'的方式。

很难说是否将此分解为单独的传奇,派遣另一个仅用于发出请求的动作是否有意义。

与往常一样,一切都取决于你的应用需求和上下文,可能做更好的东西的最佳方式是回答类似这样的问题:你提出同样的要求别的地方?你是否需要在应用程序的不同部分之间共享涉及该请求的逻辑?您需要取消或重试机制吗?