React Redux中的纯粹操作是什么?

时间:2016-11-25 00:32:00

标签: javascript reactjs callback redux react-redux

我正在学习redux saga但未通过以下方式获得作者的意思:

  

与redux thunk相反,你不会在回调地狱中结束,你可以   轻松测试你的异步流程,你的行动保持纯洁。

"回调地狱"的任何例子和纯粹的行动"非常感谢。

2 个答案:

答案 0 :(得分:3)

纯函数

纯函数是一种函数,当给定相同的参数时,总是产生相同的结果,并且不会修改任何超出其范围的变量。例如,

function addTwoIntegers(a, b) {
    return a + b;
}

如果我们传递a = 2且b = 3,则结果将始终为5.其他任何内容都不会更改。这是一件好事,因为它使测试该功能变得更加容易 - 我们确切地知道它们输出的内容对于给定的输入对。

将此与例如从API加载数据并将其分配给变量的函数进行对比:

let result;

function AddIntegerToNumberFromServer(a) {
    fetch('api/numberGenerator').then(function(res) {
       result = a + res.data.number;
    });
}

在这种情况下,我们可以多次调用具有相同参数的函数,并且不能确定获得相同的结果。这样做的结果是函数更难测试 - 我们可能必须创建一个api的模拟。我们还必须确定结果的初始值是什么,以便知道我们的功能是否按计划运行。

回调地狱

您可能知道,回调是我们作为参数传递给另一个函数的函数,因此我们可以推迟执行某些代码,直到第二个函数完成。当我们深入了解这一层时会出现回调地狱 - 正如上面有人评论jQuery似乎邀请这种风格 - 例如:

$(function() {
    $('#element').click(function() {
        $(this).fadeOut(function() {
            $('#anotherElement').fadeIn();
        }
    }
}

这里的问题主要是人类对代码的理解和易读性。想象一下,如果这更深层次(并非罕见),弄清楚发生的事情和时间是多么困难。

Redux-thunk在回调方面远远不是最糟糕的攻击者,可以通过使用promises而不是回调来减轻可读性因素。

答案 1 :(得分:1)

  

......你的行为保持纯洁......

我最好的猜测是这是一个错误。在the redux-thunk README中,没有不纯粹的动作创造者,更不用说动作对象了。也许"不纯的行为"是指"更高级别"动作 - 创建者,如makeSandwichesForEverybody包含多种副作用,因此非常难以测试。

  

...最终回调地狱......

同样makeSandwichesForEverybody包含许多嵌套的promise,随着异步工作流变得更加复杂,这些promises可能会变得难以理解。我还不能评论的是,在redux-saga中实现这个会更简单/复杂。

function makeSandwichesForEverybody() {
  return function (dispatch, getState) {
    if (!getState().sandwiches.isShopOpen) {

      // You don’t have to return Promises, but it’s a handy convention
      // so the caller can always call .then() on async dispatch result.

      return Promise.resolve();
    }

    // We can dispatch both plain object actions and other thunks,
    // which lets us compose the asynchronous actions in a single flow.

    return dispatch(
      makeASandwichWithSecretSauce('My Grandma')
    ).then(() =>
      Promise.all([
        dispatch(makeASandwichWithSecretSauce('Me')),
        dispatch(makeASandwichWithSecretSauce('My wife'))
      ])
    ).then(() =>
      dispatch(makeASandwichWithSecretSauce('Our kids'))
    ).then(() =>
      dispatch(getState().myMoney > 42 ?
        withdrawMoney(42) :
        apologize('Me', 'The Sandwich Shop')
      )
    );
  };
}

顺便说一下,我以函数的形式使用"impure action creators", which I call dispatchers,充当动作创建者,调度员并具有副作用。我发现这是管理异步工作的好模式。然而,它使同构应用更难/不可能实现,并且不容易测试。