React Redux 中的纯动作是什么?
What are pure actions in React Redux?
我正在学习redux saga但不明白作者在下面的意思:
Contrary to redux thunk, you don't end up in callback hell, you can
test your asynchronous flows easily and your actions stay pure.
任何“回调地狱”和“纯操作”的例子都将不胜感激。
纯函数
纯函数是一种函数,当给定相同的参数时,总是产生相同的结果,并且不会修改任何超出其作用域的变量.例如,
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 的模拟。我们还必须确定 result 的初始值是多少,以便知道我们的函数是否按计划工作。
回调地狱
您可能知道,回调是我们作为参数传递给另一个函数的函数,这样我们就可以推迟执行某些代码,直到第二个函数完成。当我们深入其中时,回调地狱就会发生——正如上面某人评论的那样 jQuery 似乎邀请了这种风格——例如:
$(function() {
$('#element').click(function() {
$(this).fadeOut(function() {
$('#anotherElement').fadeIn();
}
}
}
这里的问题主要是人类对代码的理解和可读性。想象一下,如果这更深入(并不少见),那么要弄清楚发生了什么以及何时发生会有多困难。
Redux-thunk 在回调方面远非最糟糕的违规者,并且可以通过使用承诺而不是回调来减轻可读性因素。
... your actions stay pure ...
我最好的猜测是这是一个错误。在 the redux-thunk README 中没有不纯的动作创建者,更不用说不纯的动作对象了。也许 "impure actions" 指的是 "higher level" action-creators 像 makeSandwichesForEverybody
这样的模式包含多种副作用,因此很难测试。
... end up in callback hell ...
同样 makeSandwichesForEverybody
包含许多嵌套的承诺,随着异步工作流程变得更加复杂,这些承诺可能会变得更难理解。我还不能评论的是这将在 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
作为动作创建者、调度器并具有副作用的函数形式。我发现这是管理异步工作的好模式。然而,它使同构应用程序更难/不可能实现并且不容易测试。
我正在学习redux saga但不明白作者在下面的意思:
Contrary to redux thunk, you don't end up in callback hell, you can test your asynchronous flows easily and your actions stay pure.
任何“回调地狱”和“纯操作”的例子都将不胜感激。
纯函数
纯函数是一种函数,当给定相同的参数时,总是产生相同的结果,并且不会修改任何超出其作用域的变量.例如,
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 的模拟。我们还必须确定 result 的初始值是多少,以便知道我们的函数是否按计划工作。
回调地狱
您可能知道,回调是我们作为参数传递给另一个函数的函数,这样我们就可以推迟执行某些代码,直到第二个函数完成。当我们深入其中时,回调地狱就会发生——正如上面某人评论的那样 jQuery 似乎邀请了这种风格——例如:
$(function() {
$('#element').click(function() {
$(this).fadeOut(function() {
$('#anotherElement').fadeIn();
}
}
}
这里的问题主要是人类对代码的理解和可读性。想象一下,如果这更深入(并不少见),那么要弄清楚发生了什么以及何时发生会有多困难。
Redux-thunk 在回调方面远非最糟糕的违规者,并且可以通过使用承诺而不是回调来减轻可读性因素。
... your actions stay pure ...
我最好的猜测是这是一个错误。在 the redux-thunk README 中没有不纯的动作创建者,更不用说不纯的动作对象了。也许 "impure actions" 指的是 "higher level" action-creators 像 makeSandwichesForEverybody
这样的模式包含多种副作用,因此很难测试。
... end up in callback hell ...
同样 makeSandwichesForEverybody
包含许多嵌套的承诺,随着异步工作流程变得更加复杂,这些承诺可能会变得更难理解。我还不能评论的是这将在 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
作为动作创建者、调度器并具有副作用的函数形式。我发现这是管理异步工作的好模式。然而,它使同构应用程序更难/不可能实现并且不容易测试。